3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-06-22 16:40:29 +00:00
This commit is contained in:
Ilana Shapiro 2026-06-21 19:29:42 -07:00
commit 35fd50238b
123 changed files with 6621 additions and 1786 deletions

View file

@ -1,7 +1,8 @@
updates:
- directory: /
ignore:
- dependency-name: "github/gh-aw-actions/**" # Managed by gh aw compile. Version-locked to the gh-aw compiler; do not bump.
- dependency-name: "github/gh-aw-actions/**"
- dependency-name: "github/gh-aw-actions" # Managed by gh aw compile. Version-locked to the gh-aw compiler; do not bump.
package-ecosystem: github-actions
schedule:
interval: weekly

View file

@ -0,0 +1,338 @@
---
name: agentic-workflow-designer
description: Conversational skill that interviews users to design new agentic workflows
disable-model-invocation: true
---
# Workflow Designer
Use this skill to run a structured interview with users who know their goal but not the workflow syntax yet, then generate one complete workflow `.md` file.
## When to Use This Skill
Use this before `.github/aw/create-agentic-workflow.md` when requirements are unclear or incomplete.
- Use `skills/agentic-workflow-designer/SKILL.md` to discover and confirm requirements.
- Use `.github/aw/create-agentic-workflow.md` once requirements are clear and ready for implementation.
- Use `.github/aw/agentic-chat.md` when the user wants a specification/pseudo-code instead of a runnable workflow file.
## Interview Framework
Ask one question at a time. Move to the next phase only after the current phase is clear.
### Phase 1: Goal
Ask: **"What do you want to automate?"**
Capture:
- Workflow name (kebab-case candidate)
- Brief description
- Optional emoji
### Phase 2: Trigger
Ask: **"When should this run?"**
Follow up only if needed:
- Which event type(s)?
- Any filters (labels, branches, commands)?
- Scheduled cadence (daily/weekly/hourly)?
Map to the `on:` block.
### Phase 3: Scope (Read/Write)
Ask:
- **"What should it read?"** (issues, PRs, code, discussions, CI data)
- **"What should it create or update?"** (comments, issues, PRs, labels)
Map to:
- `permissions:` (keep read-only for agent job)
- `tools:`
- `safe-outputs:`
### Phase 4: Data Strategy
Ask:
- **"What data does the agent need to make decisions?"**
- Follow up: **"Can we pre-fetch and aggregate that data with shell commands so the agent only reads compact JSON?"**
Capture:
- Whether `steps:` should pre-fetch GitHub data with `gh` + `jq`
- Output paths under `/tmp/gh-aw/data/`
- Whether batch work should use sub-agents
Map to:
- `steps:`
- Prompt references to pre-computed file paths
### Phase 5: Guardrails
Ask: **"Should it block merging, just advise, or silently log?"**
Capture:
- Visibility expectations (comment, issue, no visible output)
- No-op behavior expectation
Guide toward safe output behavior and explicit `noop` instructions.
### Phase 6: Context & Network
Ask: **"Does it need external APIs, web access, package installs, or MCP servers?"**
Follow up:
- **"Any third-party services or MCP servers to include (for example Slack, Jira, Datadog, custom internal MCP)?"**
- **"Are you deploying on GitHub.com, GHEC with custom endpoints, or GHES?"**
- For each integration, identify required auth from source docs and map it to GitHub Actions secrets + workflow env variables.
- Ask for exact external domains (FQDN/wildcard).
Map to:
- `network.allowed`
- Optional MCP/GitHub tool usage in `tools:`
- `secrets:` / `env:` wiring for integration tokens
- GHES/GHEC settings such as `engine.api-target` and `aw.json` `ghes: true` (when applicable)
### Phase 7: Engine (optional)
Ask only if ambiguous: **"Any AI engine preference?"**
If no preference, suggest default:
- "I'd suggest Copilot since you haven't mentioned a preference. Sound good?"
Map to `engine:` only when not default.
### Phase 8: Confirmation
Present a structured summary and ask for approval before generation.
## Decision Heuristics
### Trigger Mapping
| User says... | Maps to |
|---|---|
| "when someone opens a PR" | `on: pull_request:` with `types: [opened]` |
| "when a PR is updated" | `on: pull_request:` with `types: [opened, synchronize]` |
| "every morning", "daily" | fuzzy schedule shorthand `on: schedule: daily on weekdays` (compiler expands to cron) |
| "every Monday", "weekly" | fuzzy schedule shorthand `on: schedule: weekly` (compiler expands to cron) |
| "when I say /review" | `on: slash_command:` with `name: review` (or requested command) |
| "when an issue is labeled bug" | `on: issues:` with `types: [labeled]` and label filter guidance |
| "run when label ai-review is added" | `on: label_command:` with `name`/`names`, optional event scoping, and label-as-command semantics |
| "run on PRs from forks" | `on: pull_request:` plus explicit `forks:` allowlist and fork security guardrails |
| "sometimes automatic, sometimes manual" | semi-active pattern: combine `schedule`/event triggers with `workflow_dispatch` |
| "manually", "on demand" | `on: workflow_dispatch:` |
| "when a deployment fails" | `on: deployment_status:` |
| "when another workflow finishes" | `on: workflow_run:` |
### Safe Output Mapping
| User says... | Maps to |
|---|---|
| "post a comment" | `add-comment` |
| "create an issue" | `create-issue` |
| "update issue title/body" | `update-issue` |
| "close the issue" | `close-issue` |
| "assign someone", "remove assignment" | `assign-to-user`, `unassign-from-user` |
| "set issue type/field/milestone" | `set-issue-type`, `set-issue-field`, `assign-milestone` |
| "open a PR", "submit changes" | `create-pull-request` |
| "update PR description/title" | `update-pull-request` |
| "close the PR", "merge the PR" | `close-pull-request`, `merge-pull-request` |
| "mark PR ready", "sync PR branch" | `mark-pull-request-as-ready-for-review`, `update-branch` |
| "commit a fix to the PR branch" | `push-to-pull-request-branch` |
| "approve / request changes" | `submit-pull-request-review` |
| "inline review comment", "reply to review thread" | `create-pull-request-review-comment`, `reply-to-pull-request-review-comment`, `resolve-pull-request-review-thread` |
| "start or edit discussion", "close discussion" | `create-discussion`, `update-discussion`, `close-discussion` |
| "request reviewer", "hide comment" | `add-reviewer`, `hide-comment` |
| "create/update project", "project status update" | `create-project`, `update-project`, `create-project-status-update` |
| "update release", "upload release asset" | `update-release`, `upload-asset` |
| "create/auto-fix code scan alert" | `create-code-scanning-alert`, `autofix-code-scanning-alert` |
| "start an agent session", "assign to an agent" | `create-agent-session`, `assign-to-agent` |
| "store persistent memory comment" | `comment-memory` |
| "link a sub-issue" | `link-sub-issue` |
| "add labels", "remove labels" | `add-labels`, `remove-labels` |
| "nothing visible", "just analyze" | no safe outputs required |
### Network Mapping
| User says... | Maps to |
|---|---|
| "calls an external API" | ask for exact FQDN/wildcard, then add to `network.allowed` |
| "installs npm packages" | include `node` in `network.allowed` |
| "runs pip install" | include `python` in `network.allowed` |
| "builds Go code" | include `go` in `network.allowed` |
| "no external access" | `network.allowed: [defaults]` (or `[]` if explicitly zero network) |
### Tool Mapping
| User says... | Maps to |
|---|---|
| "read GitHub issues/PRs/workflows" | `tools.github` with `mode: gh-proxy` and minimal `toolsets` |
| "use full MCP server/tool definitions" | `tools.github` with `mode: local` |
| "use other MCP servers but keep token cost down" | `tools.cli-proxy: true` (hybrid CLI-proxy mode) |
| "edit files" | `edit` tool (default unless restricted) |
| "run commands/tests" | `bash` tool (default unless restricted) |
| "browse web pages/docs" | `web-fetch` and/or `web-search` |
| "test UI flows" | `playwright` |
### Pattern Heuristics
| User says... | Recommended named pattern |
|---|---|
| "triage issues automatically" | `IssueOps` |
| "run on /commands with human approval loops" | `ChatOps` |
| "run every weekday and keep improving" | `DailyOps` |
| "monitor workflow failures and trends" | `MonitorOps` |
| "process a big backlog in chunks" | `BatchOps` |
| "run manually with input parameters" | `DispatchOps` |
### Integration Auth Mapping
When the user names a third-party service or MCP server:
1. Confirm whether native tool, MCP server, or safe-output job is the right integration path.
2. Look up the integration's auth requirements and required scopes before finalizing the design.
3. Provide a concrete setup checklist with:
- required GitHub Actions secrets (names to create)
- workflow env variables that consume those secrets
- minimum token scopes/permissions needed
Output format to use:
```text
Integration auth setup:
- <service-or-mcp>: <purpose>
- Secrets to create: <SECRET_NAME>, <SECRET_NAME>
- Workflow env vars: <ENV_VAR>=${{ secrets.<SECRET_NAME> }}
- Required scopes/permissions: <least-privilege scopes>
```
Never suggest committing plaintext tokens.
### Data Strategy Mapping
| User says... | Maps to |
|---|---|
| "analyze PRs", "review issues", "check status" | add `steps:` that pre-fetch with `gh` + `jq` |
| "read the diff", "look at changed files" | add `steps:` using `gh pr diff` or `gh pr view --json files` |
| "search for patterns across repos" | add `steps:` using `gh search` + `jq` filters |
| "just respond to a comment" | no pre-fetch needed (event payload is enough) |
| "process each item individually" | suggest sub-agent pattern with `model: small` |
## Token Optimization Defaults
Apply these defaults unless the user explicitly asks otherwise:
1. Use DataOps by default for GitHub reads: pre-fetch/aggregate with `gh` + `jq` in `steps:`, store compact JSON in `/tmp/gh-aw/data/`, and point the prompt to those files (see `.github/aw/token-optimization.md` for details).
2. Keep tool surface minimal: default to `tools.github.mode: gh-proxy`, include only required toolsets, and prefer `bash` + `gh` for simple reads.
3. For batch workloads, split items into compact data and suggest sub-agent processing with `model: small`.
4. Keep prompts compact: concise imperative instructions, explicit file paths, single-line `noop` guidance, and stable instructions before dynamic content.
## Progressive Disclosure Rules
1. Never dump all options at once; ask one targeted question at a time.
2. Skip questions when answers are inferable from prior user statements.
3. Offer smart defaults and request confirmation instead of over-questioning.
4. Ask at most 5 questions before presenting a summary; then ask "anything else?" if needed.
5. Detect done signals (`that's it`, `looks good`, `generate it`) and proceed to generation.
## Confirmation Format
Use this exact structure:
```text
📋 Proposed workflow:
- Name: <workflow-id>
- Trigger: <event + key options>
- Engine: <engine or default>
- Tools: <tool summary>
- Safe outputs: <list or none>
- Network: <allowed summary>
- Integrations/Auth: <service/mcp + required secrets/env vars>
- Deployment: <GitHub.com or GHEC/GHES details>
- Intent: <one-sentence task>
```
Then ask: **"Ready to generate, or want to adjust anything?"**
## Generation Template
After confirmation, generate one workflow file using the same skeleton style as `.github/aw/create-agentic-workflow.md`.
```markdown
---
emoji: <emoji>
description: <brief description>
on:
<trigger config>
permissions:
contents: read
issues: read
pull-requests: read
tools:
github:
mode: gh-proxy
toolsets: [default]
steps:
- name: <optional data prefetch>
run: |
mkdir -p /tmp/gh-aw/data
<gh + jq commands that produce compact JSON>
safe-outputs:
<safe-output-types-if-needed>
network:
allowed:
- defaults
- <additional entries if needed>
---
# <Workflow Name>
## Task
<clear instructions tied to trigger context>
If `steps:` includes pre-fetch commands, read the resulting `/tmp/gh-aw/data/*.json` files instead of broad live re-fetches.
## Safe Outputs
- Use configured safe outputs for all visible write actions.
- Call `noop` with a short reason when no action is needed.
```
## Validation Checklist
Before final output, run this internal self-check:
- [ ] Agent job permissions remain read-only (writes only via safe outputs)
- [ ] `safe-outputs:` covers every write action mentioned in prompt/instructions
- [ ] Network access is scoped; avoid blanket wildcard entries
- [ ] Trigger matches the user's intended activation event
- [ ] Prompt instructs agent to call `noop` when no action is needed
- [ ] Unnecessary defaults are omitted (for example `engine: copilot`)
- [ ] If reading GitHub data, `steps:` pre-fetches compact JSON (DataOps)
- [ ] `tools.github.mode` is `gh-proxy` unless broader MCP toolsets are explicitly needed
- [ ] Only required toolsets are listed (avoid blanket toolset lists)
- [ ] Prompt references specific pre-computed file paths
- [ ] For batch processing (>5 items), sub-agent pattern is suggested
- [ ] For each third-party service/MCP integration, required secrets/env vars are listed
- [ ] Auth guidance includes least-privilege token scope recommendations
- [ ] For GHEC/GHES deployments, `engine.api-target` and GHES compatibility guidance are included when needed
## References (load only when needed)
In-repo references:
- `.github/aw/syntax.md` (index → `.github/aw/syntax-core.md`, `.github/aw/syntax-agentic.md`, `.github/aw/syntax-tools-imports.md`)
- `.github/aw/safe-outputs.md` (index → `.github/aw/safe-outputs-content.md`, `.github/aw/safe-outputs-management.md`, `.github/aw/safe-outputs-automation.md`, `.github/aw/safe-outputs-runtime.md`)
- `.github/aw/network.md`
- `.github/aw/patterns.md`
- `.github/aw/subagents.md`
- `.github/aw/token-optimization.md`
- `.github/aw/triggers.md`
- `.github/aw/create-agentic-workflow.md`
Portable HTTPS references:
- `https://github.com/github/gh-aw/blob/main/.github/aw/syntax.md` (index → `.../syntax-core.md`, `.../syntax-agentic.md`, `.../syntax-tools-imports.md`)
- `https://github.com/github/gh-aw/blob/main/.github/aw/safe-outputs.md` (index → `.../safe-outputs-content.md`, `.../safe-outputs-management.md`, `.../safe-outputs-automation.md`, `.../safe-outputs-runtime.md`)
- `https://github.com/github/gh-aw/blob/main/.github/aw/network.md`
- `https://github.com/github/gh-aw/blob/main/.github/aw/patterns.md`
- `https://github.com/github/gh-aw/blob/main/.github/aw/triggers.md`
- `https://github.com/github/gh-aw/blob/main/.github/aw/create-agentic-workflow.md`

View file

@ -1,24 +1,68 @@
---
name: agentic-workflows
description: Route gh-aw workflow create/debug/upgrade requests to the right prompts.
description: Route gh-aw workflow design/create/debug/upgrade requests to the right prompts.
---
# Agentic Workflows Router
Use this skill when a user asks to create, update, debug, or upgrade GitHub Agentic Workflows in this repository.
Use this skill when a user asks to design, create, update, debug, or upgrade GitHub Agentic Workflows in this repository.
This skill is a dispatcher: identify the task type, load the matching `.github/aw/*.md` file, and follow it directly. Keep responses concise and ask a clarifying question if the correct prompt is unclear.
This skill is a dispatcher: identify the task type, load the matching workflow prompt/skill file, and follow it directly. Keep responses concise and ask a clarifying question if the correct prompt is unclear.
Read only the files you need:
Load these files from `github/gh-aw` (they are not available locally).
- `.github/aw/agentic-chat.md`
- `.github/aw/agentic-workflows-mcp.md`
- `.github/aw/asciicharts.md`
- `.github/aw/campaign.md`
- `.github/aw/charts-trending.md`
- `.github/aw/charts.md`
- `.github/aw/cli-commands.md`
- `.github/aw/context.md`
- `.github/aw/create-agentic-workflow.md`
- `.github/aw/create-shared-agentic-workflow.md`
- `.github/aw/debug-agentic-workflow.md`
- `.github/aw/dependabot.md`
- `.github/aw/deployment-status.md`
- `.github/aw/experiments.md`
- `.github/aw/github-agentic-workflows.md`
- `.github/aw/github-mcp-server.md`
- `.github/aw/llms.md`
- `.github/aw/mcp-clis.md`
- `.github/aw/memory.md`
- `.github/aw/messages.md`
- `.github/aw/network.md`
- `.github/aw/patterns.md`
- `.github/aw/pr-reviewer.md`
- `.github/aw/report.md`
- `.github/aw/reuse.md`
- `.github/aw/safe-outputs-automation.md`
- `.github/aw/safe-outputs-content.md`
- `.github/aw/safe-outputs-management.md`
- `.github/aw/safe-outputs-runtime.md`
- `.github/aw/safe-outputs.md`
- `.github/aw/serena-tool.md`
- `.github/aw/shared-safe-jobs.md`
- `.github/aw/skills.md`
- `.github/aw/subagents.md`
- `.github/aw/syntax-agentic.md`
- `.github/aw/syntax-core.md`
- `.github/aw/syntax-tools-imports.md`
- `.github/aw/syntax.md`
- `.github/aw/test-coverage.md`
- `.github/aw/test-expression.md`
- `.github/aw/token-optimization.md`
- `.github/aw/triggers.md`
- `.github/aw/update-agentic-workflow.md`
- `.github/aw/upgrade-agentic-workflows.md`
- `.github/aw/visual-regression.md`
- `.github/aw/workflow-constraints.md`
- `.github/aw/workflow-editing.md`
- `.github/aw/workflow-patterns.md`
After loading the matching workflow prompt, follow it directly:
- `.github/skills/agentic-workflow-designer/SKILL.md`
After loading the matching workflow prompt or skill, follow it directly:
- Design workflows from scratch via interview: `skills/agentic-workflow-designer/SKILL.md`
- Create new workflows: `.github/aw/create-agentic-workflow.md`
- Update existing workflows: `.github/aw/update-agentic-workflow.md`
- Debug, audit, or investigate workflows: `.github/aw/debug-agentic-workflow.md`
@ -32,4 +76,4 @@ After loading the matching workflow prompt, follow it directly:
- Choose workflow architecture and patterns: `.github/aw/patterns.md`
- Optimize token usage and cost: `.github/aw/token-optimization.md`
When the task involves OTEL, OTLP, traces, observability backends, or telemetry-driven analysis, also read and follow `skills/otel-queries/SKILL.md` after loading the matching workflow prompt.
When the task involves OTEL, OTLP, traces, observability backends, or telemetry-driven analysis, also read and follow `skills/otel-queries/SKILL.md` after loading the matching workflow prompt or skill.

View file

@ -28,7 +28,7 @@ jobs:
runs-on: windows-latest
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v3
- run: |
@ -37,9 +37,10 @@ jobs:
${{ matrix.cmd1 }}
${{ matrix.cmd2 }}
${{ matrix.cmd3 }}
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" ${{ matrix.arch }}
cmake ${{ matrix.bindings }} -G "NMake Makefiles" ../
nmake
for /f "usebackq delims=" %%i in (`"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest -prerelease -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do set "VSPATH=%%i"
call "%VSPATH%\VC\Auxiliary\Build\vcvarsall.bat" ${{ matrix.arch }} || exit /b 1
cmake ${{ matrix.bindings }} -G "NMake Makefiles" ../ || exit /b 1
nmake || exit /b 1
cd ..
shell: cmd
- name: Run Regressions
@ -52,7 +53,8 @@ jobs:
if: ${{ matrix.test }}
run: |
pushd build
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" ${{ matrix.arch }}
for /f "usebackq delims=" %%i in (`"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest -prerelease -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do set "VSPATH=%%i"
call "%VSPATH%\VC\Auxiliary\Build\vcvarsall.bat" ${{ matrix.arch }} || exit /b 1
pushd build\python
python z3test.py z3
python z3test.py z3num

245
.github/workflows/a3-python.lock.yml generated vendored

File diff suppressed because one or more lines are too long

View file

@ -9,6 +9,7 @@ permissions:
network:
allowed: [defaults, python]
safe-outputs:
report-failure-as-issue: false
create-issue:
labels:
- bug

File diff suppressed because one or more lines are too long

View file

@ -29,6 +29,7 @@ tools:
bash: [":*"]
safe-outputs:
report-failure-as-issue: false
mentions: false
allowed-github-references: []
max-bot-mentions: 1

View file

@ -12,7 +12,7 @@
# \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \
# \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/
#
# This file was automatically generated by pkg/workflow/maintenance_workflow.go (v0.77.5). DO NOT EDIT.
# This file was automatically generated by pkg/workflow/maintenance_workflow.go (v0.79.6). DO NOT EDIT.
#
# To regenerate this workflow, run:
# gh aw compile
@ -34,7 +34,7 @@ name: Agentic Maintenance
on:
schedule:
- cron: "37 */2 * * *" # Every 2 hours (based on minimum expires: 1 days)
- cron: "37 0 * * *" # Daily (based on minimum expires: 7 days)
workflow_dispatch:
inputs:
operation:
@ -93,7 +93,7 @@ jobs:
pull-requests: write
steps:
- name: Setup Scripts
uses: github/gh-aw-actions/setup@v0.77.5
uses: github/gh-aw-actions/setup@00c24a5774577e7282046aa2225105571a8f4195 # v0.80.4
with:
destination: ${{ runner.temp }}/gh-aw/actions
@ -131,7 +131,7 @@ jobs:
actions: write
steps:
- name: Setup Scripts
uses: github/gh-aw-actions/setup@v0.77.5
uses: github/gh-aw-actions/setup@00c24a5774577e7282046aa2225105571a8f4195 # v0.80.4
with:
destination: ${{ runner.temp }}/gh-aw/actions
@ -155,12 +155,12 @@ jobs:
operation: ${{ steps.record.outputs.operation }}
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Setup Scripts
uses: github/gh-aw-actions/setup@v0.77.5
uses: github/gh-aw-actions/setup@00c24a5774577e7282046aa2225105571a8f4195 # v0.80.4
with:
destination: ${{ runner.temp }}/gh-aw/actions
@ -175,9 +175,9 @@ jobs:
await main();
- name: Install gh-aw
uses: github/gh-aw-actions/setup-cli@v0.77.5
uses: github/gh-aw-actions/setup-cli@00c24a5774577e7282046aa2225105571a8f4195 # v0.80.4
with:
version: v0.77.5
version: v0.79.6
- name: Run operation
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@ -205,7 +205,7 @@ jobs:
pull-requests: write
steps:
- name: Setup Scripts
uses: github/gh-aw-actions/setup@v0.77.5
uses: github/gh-aw-actions/setup@00c24a5774577e7282046aa2225105571a8f4195 # v0.80.4
with:
destination: ${{ runner.temp }}/gh-aw/actions
@ -244,14 +244,14 @@ jobs:
run_url: ${{ steps.record.outputs.run_url }}
steps:
- name: Checkout actions folder
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
sparse-checkout: |
actions
persist-credentials: false
- name: Setup Scripts
uses: github/gh-aw-actions/setup@v0.77.5
uses: github/gh-aw-actions/setup@00c24a5774577e7282046aa2225105571a8f4195 # v0.80.4
with:
destination: ${{ runner.temp }}/gh-aw/actions
@ -290,12 +290,12 @@ jobs:
issues: write
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Setup Scripts
uses: github/gh-aw-actions/setup@v0.77.5
uses: github/gh-aw-actions/setup@00c24a5774577e7282046aa2225105571a8f4195 # v0.80.4
with:
destination: ${{ runner.temp }}/gh-aw/actions
@ -310,9 +310,9 @@ jobs:
await main();
- name: Install gh-aw
uses: github/gh-aw-actions/setup-cli@v0.77.5
uses: github/gh-aw-actions/setup-cli@00c24a5774577e7282046aa2225105571a8f4195 # v0.80.4
with:
version: v0.77.5
version: v0.79.6
- name: Create missing labels
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@ -336,12 +336,12 @@ jobs:
issues: write
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Setup Scripts
uses: github/gh-aw-actions/setup@v0.77.5
uses: github/gh-aw-actions/setup@00c24a5774577e7282046aa2225105571a8f4195 # v0.80.4
with:
destination: ${{ runner.temp }}/gh-aw/actions
@ -356,9 +356,9 @@ jobs:
await main();
- name: Install gh-aw
uses: github/gh-aw-actions/setup-cli@v0.77.5
uses: github/gh-aw-actions/setup-cli@00c24a5774577e7282046aa2225105571a8f4195 # v0.80.4
with:
version: v0.77.5
version: v0.79.6
- name: Restore activity report logs cache
id: activity_report_logs_cache
@ -441,12 +441,12 @@ jobs:
issues: write
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Setup Scripts
uses: github/gh-aw-actions/setup@v0.77.5
uses: github/gh-aw-actions/setup@00c24a5774577e7282046aa2225105571a8f4195 # v0.80.4
with:
destination: ${{ runner.temp }}/gh-aw/actions
@ -461,15 +461,15 @@ jobs:
await main();
- name: Install gh-aw
uses: github/gh-aw-actions/setup-cli@v0.77.5
uses: github/gh-aw-actions/setup-cli@00c24a5774577e7282046aa2225105571a8f4195 # v0.80.4
with:
version: v0.77.5
version: v0.79.6
- name: Restore forecast report logs cache
id: forecast_report_logs_cache
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: .github/aw/logs
path: ./.github/aw/logs
key: ${{ runner.os }}-forecast-report-logs-${{ github.repository }}-${{ github.ref_name }}-${{ github.run_id }}
restore-keys: |
${{ runner.os }}-forecast-report-logs-${{ github.repository }}-
@ -477,24 +477,21 @@ jobs:
- name: Generate forecast report
id: generate_forecast_report
timeout-minutes: 30
shell: bash
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DEBUG: "*"
GH_AW_CMD_PREFIX: gh aw
run: |
mkdir -p ./.cache/gh-aw/forecast
${GH_AW_CMD_PREFIX} logs --repo "${{ github.repository }}" --start-date -30d --count 1500 > /dev/null
if ! compgen -G ".github/aw/logs/run-*/run_summary.json" > /dev/null; then
echo "::error::Missing run summary cache in .github/aw/logs after gh aw logs warm-up; cannot run forecast."
exit 1
fi
set +e
${GH_AW_CMD_PREFIX} forecast --repo "${{ github.repository }}" --timeout 10 --json 2> >(grep -Fv "forecast is an experimental command and may change without notice" >&2) > ./.cache/gh-aw/forecast/report.json
${GH_AW_CMD_PREFIX} forecast --repo "${{ github.repository }}" --timeout 30 --verbose --json > ./.cache/gh-aw/forecast/report.json
forecast_exit_code=$?
set -e
if [ "${forecast_exit_code}" -eq 124 ]; then
echo '{"outcome":"timeout","message":"Forecast computation timed out after 10 minutes."}' > ./.cache/gh-aw/forecast/error.json
echo "::error::Forecast computation timed out after 10 minutes."
echo '{"outcome":"timeout","message":"Forecast computation timed out after 30 minutes."}' > ./.cache/gh-aw/forecast/error.json
echo "::error::Forecast computation timed out after 30 minutes."
exit 1
fi
if [ "${forecast_exit_code}" -ne 0 ]; then
@ -503,12 +500,23 @@ jobs:
exit 1
fi
- name: Debug forecast logs folder
if: ${{ always() }}
shell: bash
run: |
if [ ! -d ./.github/aw/logs ]; then
echo "Logs directory not found: ./.github/aw/logs"
exit 0
fi
echo "Files under ./.github/aw/logs:"
find ./.github/aw/logs -type f | sort
- name: Save forecast report logs cache
if: ${{ always() }}
uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: .github/aw/logs
key: ${{ steps.forecast_report_logs_cache.outputs.cache-primary-key }}
path: ./.github/aw/logs
key: ${{ runner.os }}-forecast-report-logs-${{ github.repository }}-${{ github.ref_name }}-${{ github.run_id }}
- name: Generate forecast issue
if: ${{ always() }}
@ -530,7 +538,7 @@ jobs:
issues: write
steps:
- name: Setup Scripts
uses: github/gh-aw-actions/setup@v0.77.5
uses: github/gh-aw-actions/setup@00c24a5774577e7282046aa2225105571a8f4195 # v0.80.4
with:
destination: ${{ runner.temp }}/gh-aw/actions
@ -562,12 +570,12 @@ jobs:
issues: write
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Setup Scripts
uses: github/gh-aw-actions/setup@v0.77.5
uses: github/gh-aw-actions/setup@00c24a5774577e7282046aa2225105571a8f4195 # v0.80.4
with:
destination: ${{ runner.temp }}/gh-aw/actions
@ -582,9 +590,9 @@ jobs:
await main();
- name: Install gh-aw
uses: github/gh-aw-actions/setup-cli@v0.77.5
uses: github/gh-aw-actions/setup-cli@00c24a5774577e7282046aa2225105571a8f4195 # v0.80.4
with:
version: v0.77.5
version: v0.79.6
- name: Validate workflows and file issue on findings
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0

View file

@ -22,7 +22,7 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Configure CMake and build
run: |
@ -33,7 +33,7 @@ jobs:
tar -cvf z3-build-${{ matrix.android-abi }}.tar *.jar *.so
- name: Archive production artifacts
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: android-build-${{ matrix.android-abi }}
path: build/z3-build-${{ matrix.android-abi }}.tar

File diff suppressed because one or more lines are too long

View file

@ -20,6 +20,7 @@ tools:
web-search: {}
safe-outputs:
report-failure-as-issue: false
create-discussion:
title-prefix: "[API Coherence] "
category: "Agentic Workflows"

File diff suppressed because one or more lines are too long

View file

@ -8,6 +8,7 @@ tools:
edit:
bash: true
safe-outputs:
report-failure-as-issue: false
create-pull-request:
if-no-changes: ignore
missing-tool:

View file

@ -29,7 +29,7 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6

View file

@ -38,7 +38,7 @@ jobs:
runRegressions: false
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -81,7 +81,7 @@ jobs:
container: "quay.io/pypa/manylinux_2_34_x86_64:latest"
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Select Python
run: |
@ -121,7 +121,7 @@ jobs:
container: quay.io/pypa/manylinux_2_28_x86_64:latest
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Download ARM toolchain
run: curl -L -o /tmp/arm-toolchain.tar.xz 'https://developer.arm.com/-/media/Files/downloads/gnu/13.3.rel1/binrel/arm-gnu-toolchain-13.3.rel1-x86_64-aarch64-none-linux-gnu.tar.xz'
@ -165,7 +165,7 @@ jobs:
timeout-minutes: 90
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup OCaml
uses: ocaml/setup-ocaml@v3
@ -220,7 +220,7 @@ jobs:
timeout-minutes: 90
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup OCaml
uses: ocaml/setup-ocaml@v3
@ -314,7 +314,7 @@ jobs:
runTests: false
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -404,7 +404,7 @@ jobs:
timeout-minutes: 90
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -453,7 +453,7 @@ jobs:
timeout-minutes: 90
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -494,7 +494,7 @@ jobs:
timeout-minutes: 10
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -514,7 +514,7 @@ jobs:
timeout-minutes: 90
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6

File diff suppressed because one or more lines are too long

View file

@ -15,6 +15,7 @@ tools:
- "git diff:*"
- "git show:*"
safe-outputs:
report-failure-as-issue: false
create-issue:
title-prefix: "[Conventions] "
labels: [code-quality, automated]

View file

@ -1,5 +1,5 @@
# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"a50e58358dfcf5d6e6e0b92707925040a7b1ad4f29c08cfce11cfa8c9756f876","body_hash":"368645de189baaa1bf33102a20d4c9ea646e5ed15d3d2bffaf4b221f6c97b73b","compiler_version":"v0.77.5","strict":true,"agent_id":"copilot"}
# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/github-script","sha":"v9","version":"v9"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"v0.77.5","version":"v0.77.5"}],"resolution_failures":[{"repo":"actions/github-script","ref":"v9","error_type":"dynamic_resolution_failed"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.58"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.58"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.58"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.22"},{"image":"ghcr.io/github/github-mcp-server:v1.1.0"},{"image":"node:lts-alpine","digest":"sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f","pinned_image":"node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f"}]}
# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"43d46b9fb0525b484e4cd15d3251010e0b2b854cb91a250eb32c44c5402c5985","body_hash":"368645de189baaa1bf33102a20d4c9ea646e5ed15d3d2bffaf4b221f6c97b73b","compiler_version":"v0.79.6","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.60"}}
# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"df4cb1c069e1874edd31b4311f1884172cec0e10","version":"v6.0.3"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/github-script","sha":"v9","version":"v9"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"v0.79.6","version":"v0.79.6"}],"resolution_failures":[{"repo":"actions/github-script","ref":"v9","error_type":"dynamic_resolution_failed"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.2","digest":"sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2","digest":"sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.2","digest":"sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.25","digest":"sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa"},{"image":"ghcr.io/github/github-mcp-server:v1.1.2","digest":"sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c","pinned_image":"ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c"}]}
# ___ _ _
# / _ \ | | (_)
# | |_| | __ _ ___ _ __ | |_ _ ___
@ -14,7 +14,7 @@
# \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \
# \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/
#
# This file was automatically generated by gh-aw (v0.77.5). DO NOT EDIT.
# This file was automatically generated by gh-aw (v0.79.6). DO NOT EDIT.
#
# To update this file, edit github/gh-aw/.github/workflows/code-simplifier.md@6762bfba6ae426a03aac46e8f68701461c667404 and run:
# gh aw compile
@ -34,21 +34,20 @@
# - GITHUB_TOKEN
#
# Custom actions used:
# - actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# - actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
# - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
# - actions/github-script@v9
# - actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
# - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
# - github/gh-aw-actions/setup@v0.77.5
# - github/gh-aw-actions/setup@v0.80.4
#
# Container images used:
# - ghcr.io/github/gh-aw-firewall/agent:0.25.58
# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.58
# - ghcr.io/github/gh-aw-firewall/squid:0.25.58
# - ghcr.io/github/gh-aw-mcpg:v0.3.22
# - ghcr.io/github/github-mcp-server:v1.1.0
# - node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f
# - ghcr.io/github/gh-aw-firewall/agent:0.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6
# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4
# - ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591
# - ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa
# - ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c
name: "Code Simplifier"
on:
@ -79,9 +78,14 @@ jobs:
permissions:
actions: read
contents: read
env:
GH_AW_MAX_DAILY_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_DAILY_AI_CREDITS || '5000' }}
outputs:
comment_id: ""
comment_repo: ""
daily_effective_workflow_exceeded: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_effective_workflow_exceeded == 'true' }}
daily_effective_workflow_threshold: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_effective_workflow_threshold || '' }}
daily_effective_workflow_total_effective_tokens: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_effective_workflow_total_effective_tokens || '' }}
engine_id: ${{ steps.generate_aw_info.outputs.engine_id }}
lockdown_check_failed: ${{ steps.generate_aw_info.outputs.lockdown_check_failed == 'true' }}
model: ${{ steps.generate_aw_info.outputs.model }}
@ -93,17 +97,18 @@ jobs:
steps:
- name: Setup Scripts
id: setup
uses: github/gh-aw-actions/setup@v0.77.5
uses: github/gh-aw-actions/setup@v0.80.4
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
trace-id: ${{ needs.pre_activation.outputs.setup-trace-id }}
parent-span-id: ${{ needs.pre_activation.outputs.setup-parent-span-id || needs.pre_activation.outputs.setup-span-id }}
safe-output-artifact-client: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
env:
GH_AW_SETUP_WORKFLOW_NAME: "Code Simplifier"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/code-simplifier.lock.yml@${{ github.ref }}
GH_AW_INFO_VERSION: "1.0.55"
GH_AW_INFO_AWF_VERSION: "v0.25.58"
GH_AW_INFO_VERSION: "1.0.60"
GH_AW_INFO_AWF_VERSION: "v0.27.2"
GH_AW_INFO_BODY_MODIFIED: "false"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Generate agentic run info
@ -112,16 +117,16 @@ jobs:
GH_AW_INFO_ENGINE_ID: "copilot"
GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI"
GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'claude-sonnet-4.6' }}
GH_AW_INFO_VERSION: "1.0.55"
GH_AW_INFO_AGENT_VERSION: "1.0.55"
GH_AW_INFO_CLI_VERSION: "v0.77.5"
GH_AW_INFO_VERSION: "1.0.60"
GH_AW_INFO_AGENT_VERSION: "1.0.60"
GH_AW_INFO_CLI_VERSION: "v0.79.6"
GH_AW_INFO_WORKFLOW_NAME: "Code Simplifier"
GH_AW_INFO_EXPERIMENTAL: "false"
GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
GH_AW_INFO_STAGED: "false"
GH_AW_INFO_ALLOWED_DOMAINS: '["go"]'
GH_AW_INFO_FIREWALL_ENABLED: "true"
GH_AW_INFO_AWF_VERSION: "v0.25.58"
GH_AW_INFO_AWF_VERSION: "v0.27.2"
GH_AW_INFO_AWMG_VERSION: ""
GH_AW_INFO_FIREWALL_TYPE: "squid"
GH_AW_INFO_FRONTMATTER_SOURCE: "github/gh-aw/.github/workflows/code-simplifier.md@6762bfba6ae426a03aac46e8f68701461c667404"
@ -134,13 +139,31 @@ jobs:
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs');
await main(core, context);
- name: Check daily workflow token guardrail
id: daily-effective-workflow-guardrail
if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
GH_AW_WORKFLOW_NAME: "Code Simplifier"
GH_AW_WORKFLOW_ID: "code-simplifier"
GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
GH_AW_WORKFLOW_DISPATCH_AW_CONTEXT: ${{ github.event.inputs.aw_context || '' }}
GH_AW_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_AW_MAX_DAILY_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_DAILY_AI_CREDITS || '5000' }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/check_daily_aic_workflow_guardrail.cjs');
await main();
- name: Validate COPILOT_GITHUB_TOKEN secret
id: validate-secret
run: bash "${RUNNER_TEMP}/gh-aw/actions/validate_multi_secret.sh" COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default
env:
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
- name: Checkout .github and .agents folders
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
sparse-checkout: |
@ -176,7 +199,7 @@ jobs:
- name: Check compile-agentic version
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
GH_AW_COMPILED_VERSION: "v0.77.5"
GH_AW_COMPILED_VERSION: "v0.79.6"
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@ -199,23 +222,23 @@ jobs:
run: |
bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh"
{
cat << 'GH_AW_PROMPT_b6435d392c5b00fb_EOF'
cat << 'GH_AW_PROMPT_ddf86d6f4f3fea64_EOF'
<system>
GH_AW_PROMPT_b6435d392c5b00fb_EOF
GH_AW_PROMPT_ddf86d6f4f3fea64_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_b6435d392c5b00fb_EOF'
cat << 'GH_AW_PROMPT_ddf86d6f4f3fea64_EOF'
<safe-output-tools>
Tools: create_pull_request, missing_tool, missing_data, noop
GH_AW_PROMPT_b6435d392c5b00fb_EOF
GH_AW_PROMPT_ddf86d6f4f3fea64_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_create_pull_request.md"
cat << 'GH_AW_PROMPT_b6435d392c5b00fb_EOF'
cat << 'GH_AW_PROMPT_ddf86d6f4f3fea64_EOF'
</safe-output-tools>
GH_AW_PROMPT_b6435d392c5b00fb_EOF
GH_AW_PROMPT_ddf86d6f4f3fea64_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md"
cat << 'GH_AW_PROMPT_b6435d392c5b00fb_EOF'
cat << 'GH_AW_PROMPT_ddf86d6f4f3fea64_EOF'
<github-context>
The following GitHub context information is available for this workflow:
{{#if github.actor}}
@ -244,12 +267,12 @@ jobs:
{{/if}}
</github-context>
GH_AW_PROMPT_b6435d392c5b00fb_EOF
GH_AW_PROMPT_ddf86d6f4f3fea64_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
cat << 'GH_AW_PROMPT_b6435d392c5b00fb_EOF'
cat << 'GH_AW_PROMPT_ddf86d6f4f3fea64_EOF'
</system>
{{#runtime-import .github/workflows/code-simplifier.md}}
GH_AW_PROMPT_b6435d392c5b00fb_EOF
GH_AW_PROMPT_ddf86d6f4f3fea64_EOF
} > "$GH_AW_PROMPT"
- name: Interpolate variables and render templates
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@ -320,6 +343,7 @@ jobs:
path: |
/tmp/gh-aw/aw_info.json
/tmp/gh-aw/model_multipliers.json
/tmp/gh-aw/models.json
/tmp/gh-aw/aw-prompts/prompt.txt
/tmp/gh-aw/aw-prompts/prompt-template.txt
/tmp/gh-aw/aw-prompts/prompt-import-tree.json
@ -332,6 +356,7 @@ jobs:
agent:
needs: activation
if: needs.activation.outputs.daily_effective_workflow_exceeded != 'true'
runs-on: ubuntu-latest
permissions:
contents: read
@ -349,9 +374,11 @@ jobs:
GH_AW_WORKFLOW_ID_SANITIZED: codesimplifier
outputs:
agentic_engine_timeout: ${{ steps.detect-agent-errors.outputs.agentic_engine_timeout || 'false' }}
ai_credits_rate_limit_error: ${{ steps.parse-mcp-gateway.outputs.ai_credits_rate_limit_error || 'false' }}
aic: ${{ steps.parse-mcp-gateway.outputs.aic }}
ambient_context: ${{ steps.parse-mcp-gateway.outputs.ambient_context }}
checkout_pr_success: ${{ steps.checkout-pr.outputs.checkout_pr_success || 'true' }}
effective_tokens: ${{ steps.parse-mcp-gateway.outputs.effective_tokens }}
effective_tokens_rate_limit_error: ${{ steps.parse-mcp-gateway.outputs.effective_tokens_rate_limit_error || 'false' }}
has_patch: ${{ steps.collect_output.outputs.has_patch }}
inference_access_error: ${{ steps.detect-agent-errors.outputs.inference_access_error || 'false' }}
mcp_policy_error: ${{ steps.detect-agent-errors.outputs.mcp_policy_error || 'false' }}
@ -362,10 +389,11 @@ jobs:
setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
setup-span-id: ${{ steps.setup.outputs.span-id }}
setup-trace-id: ${{ steps.setup.outputs.trace-id }}
unknown_model_ai_credits: ${{ steps.parse-mcp-gateway.outputs.unknown_model_ai_credits || 'false' }}
steps:
- name: Setup Scripts
id: setup
uses: github/gh-aw-actions/setup@v0.77.5
uses: github/gh-aw-actions/setup@v0.80.4
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@ -374,8 +402,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "Code Simplifier"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/code-simplifier.lock.yml@${{ github.ref }}
GH_AW_INFO_VERSION: "1.0.55"
GH_AW_INFO_AWF_VERSION: "v0.25.58"
GH_AW_INFO_VERSION: "1.0.60"
GH_AW_INFO_AWF_VERSION: "v0.27.2"
GH_AW_INFO_BODY_MODIFIED: "false"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Set runtime paths
@ -387,7 +415,7 @@ jobs:
echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json"
} >> "$GITHUB_OUTPUT"
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Create gh-aw temp directory
@ -412,7 +440,7 @@ jobs:
- name: Checkout PR branch
id: checkout-pr
if: |
github.event.pull_request || github.event.issue.pull_request
github.event.pull_request || github.event.issue.pull_request || github.event_name == 'workflow_dispatch' && fromJSON(github.event.inputs.aw_context || '{}').item_type == 'pull_request'
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
@ -424,11 +452,11 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs');
await main();
- name: Install GitHub Copilot CLI
run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.55
run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.60
env:
GH_HOST: github.com
- name: Install AWF binary
run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.58
run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.2
- name: Determine automatic lockdown mode for GitHub MCP Server
id: determine-automatic-lockdown
uses: actions/github-script@v9
@ -460,15 +488,15 @@ jobs:
GH_AW_SKILL_DIR: ".github/skills"
run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_skills.sh"
- name: Download container images
run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.58 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.58 ghcr.io/github/gh-aw-firewall/squid:0.25.58 ghcr.io/github/gh-aw-mcpg:v0.3.22 ghcr.io/github/github-mcp-server:v1.1.0 node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f
run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4 ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591 ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c
- name: Generate Safe Outputs Config
run: |
mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs"
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_9974579f3008b6e7_EOF'
cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_7eb77ba1d1f9c017_EOF'
{"create_pull_request":{"expires":24,"labels":["refactoring","code-quality","automation"],"max":1,"max_patch_files":100,"max_patch_size":1024,"protect_top_level_dot_folders":true,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","DESIGN.md","README.md","CONTRIBUTING.md","CHANGELOG.md","SECURITY.md","CODE_OF_CONDUCT.md","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_files_policy":"request_review","reviewers":["copilot"],"title_prefix":"[code-simplifier] "},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"false"},"report_incomplete":{}}
GH_AW_SAFE_OUTPUTS_CONFIG_9974579f3008b6e7_EOF
GH_AW_SAFE_OUTPUTS_CONFIG_7eb77ba1d1f9c017_EOF
- name: Generate Safe Outputs Tools
env:
GH_AW_TOOLS_META_JSON: |
@ -677,16 +705,16 @@ jobs:
* ) DOCKER_SOCK_PATH=/var/run/docker.sock ;;
esac
DOCKER_SOCK_GID=$(stat -c '%g' "$DOCKER_SOCK_PATH" 2>/dev/null || echo '0')
export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.3.22'
export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.3.25'
mkdir -p /home/runner/.copilot
GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node)
cat << GH_AW_MCP_CONFIG_14204ee419df0c42_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
cat << GH_AW_MCP_CONFIG_c6fee03c27b97257_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
{
"mcpServers": {
"github": {
"type": "stdio",
"container": "ghcr.io/github/github-mcp-server:v1.1.0",
"container": "ghcr.io/github/github-mcp-server:v1.1.2",
"env": {
"GITHUB_HOST": "\${GITHUB_SERVER_URL}",
"GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}",
@ -722,7 +750,7 @@ jobs:
"payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}"
}
}
GH_AW_MCP_CONFIG_14204ee419df0c42_EOF
GH_AW_MCP_CONFIG_c6fee03c27b97257_EOF
- name: Mount MCP servers as CLIs
id: mount-mcp-clis
continue-on-error: true
@ -751,14 +779,19 @@ jobs:
run: |
set -o pipefail
printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt
trap 'rm -f /home/runner/.copilot/settings.json' EXIT
mkdir -p /home/runner/.copilot
printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > /home/runner/.copilot/settings.json
touch /tmp/gh-aw/agent-step-summary.md
GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true)
export GH_AW_NODE_BIN
export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK"
(umask 177 && touch /tmp/gh-aw/agent-stdio.log)
printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.58/awf-config.schema.json","network":{"allowDomains":["api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.individual.githubcopilot.com","github.com","go.dev","golang.org","goproxy.io","host.docker.internal","pkg.go.dev","proxy.golang.org","raw.githubusercontent.com","registry.npmjs.org","storage.googleapis.com","sum.golang.org","telemetry.enterprise.githubcopilot.com"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxEffectiveTokens":25000000,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex"],"computer-use":["copilot/*computer-use*","google/*computer-use*","gemini/*computer-use*","openai/*computer-use*"],"copilot":["agent"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"gemini":["agent"],"gemini-3-flash":["copilot/gemini-3*flash*","google/gemini-3*flash*","gemini/gemini-3*flash*"],"gemini-3-pro":["copilot/gemini-3*pro*","google/gemini-3*pro*","gemini/gemini-3*pro*"],"gemini-3.1-flash":["copilot/gemini-3.1*flash*","google/gemini-3.1*flash*","gemini/gemini-3.1*flash*"],"gemini-3.1-pro":["copilot/gemini-3.1*pro*","google/gemini-3.1*pro*","gemini/gemini-3.1*pro*"],"gemini-3.5-flash":["copilot/gemini-3.5*flash*","google/gemini-3.5*flash*","gemini/gemini-3.5*flash*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"gpt-5.2":["copilot/gpt-5.2*","openai/gpt-5.2*"],"gpt-5.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"gpt-5.5":["copilot/gpt-5.5*","openai/gpt-5.5*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"opus":["copilot/*opus*","anthropic/*opus*"],"opusplan":["opus?effort=high"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"robotics":["copilot/*robotics*","google/*robotics*","gemini/*robotics*"],"small":["mini"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["copilot/*sonnet-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"vision":["copilot/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.25.58"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json"
GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_MAX_AI_CREDITS || '1000' }}"
printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.2/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"go.dev\",\"golang.org\",\"goproxy.io\",\"host.docker.internal\",\"pkg.go.dev\",\"proxy.golang.org\",\"raw.githubusercontent.com\",\"registry.npmjs.org\",\"storage.googleapis.com\",\"sum.golang.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"vision\":[\"copilot/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.2,squid=sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591,agent=sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6,api-proxy=sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4,cli-proxy=sha256:02f3ec08f32dc26c5427920c6a2e2f3036238fce44802f2f11ef49ed8621b5d0\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
GH_AW_MODEL_MULTIPLIERS_PATH="/tmp/gh-aw/model_multipliers.json" node "${RUNNER_TEMP}/gh-aw/actions/merge_awf_model_multipliers.cjs"
cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json
export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json"
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
@ -774,18 +807,20 @@ jobs:
fi
# shellcheck disable=SC1003
sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
-- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"; export PATH="$(find "$GH_AW_TOOL_CACHE" /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
-- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"; export PATH="$(find "$GH_AW_TOOL_CACHE" /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
env:
AWF_REFLECT_ENABLED: 1
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
COPILOT_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'claude-sonnet-4.6' }}
GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
GH_AW_MCP_CONFIG: /home/runner/.copilot/mcp-config.json
GH_AW_PHASE: agent
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
GH_AW_VERSION: v0.77.5
GH_AW_TIMEOUT_MINUTES: 30
GH_AW_VERSION: v0.79.6
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
@ -968,7 +1003,7 @@ jobs:
- safe_outputs
if: >
always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' ||
needs.activation.outputs.stale_lock_file_failed == 'true')
needs.activation.outputs.stale_lock_file_failed == 'true' || needs.activation.outputs.daily_effective_workflow_exceeded == 'true')
runs-on: ubuntu-slim
permissions:
contents: write
@ -986,7 +1021,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
uses: github/gh-aw-actions/setup@v0.77.5
uses: github/gh-aw-actions/setup@v0.80.4
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@ -995,8 +1030,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "Code Simplifier"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/code-simplifier.lock.yml@${{ github.ref }}
GH_AW_INFO_VERSION: "1.0.55"
GH_AW_INFO_AWF_VERSION: "v0.25.58"
GH_AW_INFO_VERSION: "1.0.60"
GH_AW_INFO_AWF_VERSION: "v0.27.2"
GH_AW_INFO_BODY_MODIFIED: "false"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
@ -1013,6 +1048,40 @@ jobs:
mkdir -p /tmp/gh-aw/
find "/tmp/gh-aw/" -type f -print
echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
- name: Collect usage artifact files
if: always()
continue-on-error: true
run: |
mkdir -p /tmp/gh-aw/usage/agent /tmp/gh-aw/usage/detection
echo "Usage artifact source file status:"
for file in /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do
[ -f "$file" ] && echo "FOUND: $file" || echo "MISSING: $file"
done
[ -f /tmp/gh-aw/aw-info.jsonl ] && cp /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/usage/aw-info.jsonl || true
[ -f /tmp/gh-aw/agent_usage.jsonl ] && cp /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/usage/agent_usage.jsonl || true
[ -f /tmp/gh-aw/detection_usage.jsonl ] && cp /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl || true
[ -f /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
[ -f /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
[ -f /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
[ -f /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true
[ -f /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true
[ -f /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true
[ -f /tmp/gh-aw/usage/agent/token_usage.jsonl ] || : > /tmp/gh-aw/usage/agent/token_usage.jsonl
[ -f /tmp/gh-aw/usage/detection/token_usage.jsonl ] || : > /tmp/gh-aw/usage/detection/token_usage.jsonl
find /tmp/gh-aw/usage -type f -print | sort
- name: Upload usage artifact
if: always()
continue-on-error: true
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: usage
path: |
/tmp/gh-aw/usage/aw-info.jsonl
/tmp/gh-aw/usage/agent_usage.jsonl
/tmp/gh-aw/usage/detection_usage.jsonl
/tmp/gh-aw/usage/agent/token_usage.jsonl
/tmp/gh-aw/usage/detection/token_usage.jsonl
if-no-files-found: ignore
- name: Process no-op messages
id: noop
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@ -1026,6 +1095,10 @@ jobs:
GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
GH_AW_NOOP_REPORT_AS_ISSUE: "false"
GH_AW_AIC: ${{ needs.agent.outputs.aic }}
GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }}
GH_AW_AMBIENT_CONTEXT: ${{ needs.agent.outputs.ambient_context }}
GH_AW_WORKFLOW_ID: "code-simplifier"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
@ -1104,7 +1177,11 @@ jobs:
GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.activation.outputs.secret_verification_result }}
GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }}
GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens || '' }}
GH_AW_EFFECTIVE_TOKENS_RATE_LIMIT_ERROR: ${{ needs.agent.outputs.effective_tokens_rate_limit_error || 'false' }}
GH_AW_AI_CREDITS_RATE_LIMIT_ERROR: ${{ needs.agent.outputs.ai_credits_rate_limit_error || 'false' }}
GH_AW_UNKNOWN_MODEL_AI_CREDITS: ${{ needs.agent.outputs.unknown_model_ai_credits || 'false' }}
GH_AW_AIC: ${{ needs.agent.outputs.aic }}
GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }}
GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_AI_CREDITS || '1000' }}
GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }}
GH_AW_MCP_POLICY_ERROR: ${{ needs.agent.outputs.mcp_policy_error }}
GH_AW_AGENTIC_ENGINE_TIMEOUT: ${{ needs.agent.outputs.agentic_engine_timeout }}
@ -1114,12 +1191,14 @@ jobs:
GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }}
GH_AW_LOCKDOWN_CHECK_FAILED: ${{ needs.activation.outputs.lockdown_check_failed }}
GH_AW_STALE_LOCK_FILE_FAILED: ${{ needs.activation.outputs.stale_lock_file_failed }}
GH_AW_DAILY_EFFECTIVE_WORKFLOW_EXCEEDED: ${{ needs.activation.outputs.daily_effective_workflow_exceeded }}
GH_AW_DAILY_EFFECTIVE_WORKFLOW_TOTAL_EFFECTIVE_TOKENS: ${{ needs.activation.outputs.daily_effective_workflow_total_effective_tokens }}
GH_AW_DAILY_EFFECTIVE_WORKFLOW_THRESHOLD: ${{ needs.activation.outputs.daily_effective_workflow_threshold }}
GH_AW_GROUP_REPORTS: "false"
GH_AW_FAILURE_REPORT_AS_ISSUE: "true"
GH_AW_FAILURE_REPORT_AS_ISSUE: "false"
GH_AW_MISSING_TOOL_REPORT_AS_FAILURE: "true"
GH_AW_MISSING_DATA_REPORT_AS_FAILURE: "true"
GH_AW_TIMEOUT_MINUTES: "30"
GH_AW_MAX_EFFECTIVE_TOKENS: "25000000"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
@ -1138,13 +1217,14 @@ jobs:
permissions:
contents: read
outputs:
aic: ${{ steps.parse_detection_token_usage.outputs.aic }}
detection_conclusion: ${{ steps.detection_conclusion.outputs.conclusion }}
detection_reason: ${{ steps.detection_conclusion.outputs.reason }}
detection_success: ${{ steps.detection_conclusion.outputs.success }}
steps:
- name: Setup Scripts
id: setup
uses: github/gh-aw-actions/setup@v0.77.5
uses: github/gh-aw-actions/setup@v0.80.4
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@ -1153,8 +1233,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "Code Simplifier"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/code-simplifier.lock.yml@${{ github.ref }}
GH_AW_INFO_VERSION: "1.0.55"
GH_AW_INFO_AWF_VERSION: "v0.25.58"
GH_AW_INFO_VERSION: "1.0.60"
GH_AW_INFO_AWF_VERSION: "v0.27.2"
GH_AW_INFO_BODY_MODIFIED: "false"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
@ -1173,7 +1253,7 @@ jobs:
echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
- name: Checkout repository for patch context
if: needs.agent.outputs.has_patch == 'true'
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
# --- Threat Detection ---
@ -1182,7 +1262,7 @@ jobs:
rm -rf /tmp/gh-aw/sandbox/firewall/logs
rm -rf /tmp/gh-aw/sandbox/firewall/audit
- name: Download container images
run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.58 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.58 ghcr.io/github/gh-aw-firewall/squid:0.25.58
run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4 ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591
- name: Check if detection needed
id: detection_guard
if: always()
@ -1207,6 +1287,7 @@ jobs:
if: always() && steps.detection_guard.outputs.run_detection == 'true'
run: |
mkdir -p /tmp/gh-aw/threat-detection/aw-prompts
rm -f /tmp/gh-aw/agent_usage.json
cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true
if [ ! -s /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt ]; then
echo "::warning::ERR_VALIDATION: Missing or empty detection context prompt at /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt. Ensure the agent artifact includes /tmp/gh-aw/aw-prompts/prompt.txt. Detection will continue with fallback workflow context."
@ -1244,11 +1325,11 @@ jobs:
node-version: '24'
package-manager-cache: false
- name: Install GitHub Copilot CLI
run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.55
run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.60
env:
GH_HOST: github.com
- name: Install AWF binary
run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.58
run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.2
- name: Execute GitHub Copilot CLI
if: always() && steps.detection_guard.outputs.run_detection == 'true'
continue-on-error: true
@ -1258,14 +1339,19 @@ jobs:
run: |
set -o pipefail
printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt
trap 'rm -f /home/runner/.copilot/settings.json' EXIT
mkdir -p /home/runner/.copilot
printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > /home/runner/.copilot/settings.json
touch /tmp/gh-aw/agent-step-summary.md
GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true)
export GH_AW_NODE_BIN
export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK"
(umask 177 && touch /tmp/gh-aw/threat-detection/detection.log)
printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.58/awf-config.schema.json","network":{"allowDomains":["api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.individual.githubcopilot.com","github.com","host.docker.internal","registry.npmjs.org","telemetry.enterprise.githubcopilot.com"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxEffectiveTokens":25000000},"container":{"imageTag":"0.25.58"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json"
GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}"
printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.2/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS}},\"container\":{\"imageTag\":\"0.27.2,squid=sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591,agent=sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6,api-proxy=sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4,cli-proxy=sha256:02f3ec08f32dc26c5427920c6a2e2f3036238fce44802f2f11ef49ed8621b5d0\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
GH_AW_MODEL_MULTIPLIERS_PATH="/tmp/gh-aw/model_multipliers.json" node "${RUNNER_TEMP}/gh-aw/actions/merge_awf_model_multipliers.cjs"
cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json
export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json"
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
@ -1281,16 +1367,18 @@ jobs:
fi
# shellcheck disable=SC1003
sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
-- /bin/bash -c 'set +o histexpand; GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"; export PATH="$(find "$GH_AW_TOOL_CACHE" /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
-- /bin/bash -c 'set +o histexpand; GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"; export PATH="$(find "$GH_AW_TOOL_CACHE" /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
env:
AWF_REFLECT_ENABLED: 1
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'claude-sonnet-4.6' }}
GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
GH_AW_PHASE: detection
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
GH_AW_VERSION: v0.77.5
GH_AW_TIMEOUT_MINUTES: 20
GH_AW_VERSION: v0.79.6
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
@ -1305,6 +1393,19 @@ jobs:
GIT_COMMITTER_NAME: github-actions[bot]
RUNNER_TEMP: ${{ runner.temp }}
XDG_CONFIG_HOME: /home/runner
- name: Parse threat detection token usage for step summary
id: parse_detection_token_usage
if: always()
continue-on-error: true
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs');
await main();
- name: Upload threat detection log
if: always() && steps.detection_guard.outputs.run_detection == 'true'
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
@ -1356,15 +1457,15 @@ jobs:
steps:
- name: Setup Scripts
id: setup
uses: github/gh-aw-actions/setup@v0.77.5
uses: github/gh-aw-actions/setup@v0.80.4
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
env:
GH_AW_SETUP_WORKFLOW_NAME: "Code Simplifier"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/code-simplifier.lock.yml@${{ github.ref }}
GH_AW_INFO_VERSION: "1.0.55"
GH_AW_INFO_AWF_VERSION: "v0.25.58"
GH_AW_INFO_VERSION: "1.0.60"
GH_AW_INFO_AWF_VERSION: "v0.27.2"
GH_AW_INFO_BODY_MODIFIED: "false"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Check team membership for workflow
@ -1404,15 +1505,19 @@ jobs:
contents: write
issues: write
pull-requests: write
timeout-minutes: 15
timeout-minutes: 45
env:
GH_AW_AGENT_AIC: ${{ needs.agent.outputs.aic }}
GH_AW_AIC: ${{ needs.agent.outputs.aic }}
GH_AW_AMBIENT_CONTEXT: ${{ needs.agent.outputs.ambient_context }}
GH_AW_CALLER_WORKFLOW_ID: "${{ github.repository }}/code-simplifier"
GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }}
GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }}
GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }}
GH_AW_ENGINE_ID: "copilot"
GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }}
GH_AW_ENGINE_VERSION: "1.0.55"
GH_AW_ENGINE_VERSION: "1.0.60"
GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }}
GH_AW_TRACKER_ID: "code-simplifier"
GH_AW_WORKFLOW_ID: "code-simplifier"
GH_AW_WORKFLOW_NAME: "Code Simplifier"
@ -1430,7 +1535,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
uses: github/gh-aw-actions/setup@v0.77.5
uses: github/gh-aw-actions/setup@v0.80.4
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@ -1439,8 +1544,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "Code Simplifier"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/code-simplifier.lock.yml@${{ github.ref }}
GH_AW_INFO_VERSION: "1.0.55"
GH_AW_INFO_AWF_VERSION: "v0.25.58"
GH_AW_INFO_VERSION: "1.0.60"
GH_AW_INFO_AWF_VERSION: "v0.27.2"
GH_AW_INFO_BODY_MODIFIED: "false"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
@ -1475,7 +1580,7 @@ jobs:
await main();
- name: Checkout repository (trusted default branch for comment events)
if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'create_pull_request') && (github.event_name == 'issue_comment' || github.event_name == 'pull_request_review_comment')
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
ref: ${{ github.event.repository.default_branch }}
token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
@ -1483,7 +1588,7 @@ jobs:
fetch-depth: 1
- name: Checkout repository
if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'create_pull_request') && github.event_name != 'issue_comment' && github.event_name != 'pull_request_review_comment'
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
ref: ${{ steps.extract-base-branch.outputs.base-branch || github.base_ref || github.event.pull_request.base.ref || github.ref_name || github.event.repository.default_branch }}
token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
@ -1506,6 +1611,7 @@ jobs:
- name: Configure GH_HOST for enterprise compatibility
id: ghes-host-config
shell: bash
# zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
run: |
# Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
# GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.

View file

@ -14,6 +14,7 @@ tracker-id: code-simplifier
safe-outputs:
report-failure-as-issue: false
create-pull-request:
title-prefix: "[code-simplifier] "
labels: [refactoring, code-quality, automation]

File diff suppressed because one or more lines are too long

View file

@ -22,6 +22,7 @@ tools:
toolsets: [default]
safe-outputs:
report-failure-as-issue: false
create-discussion:
title-prefix: "[Compare Stats] "
category: "agentic workflows"

View file

@ -19,7 +19,7 @@ jobs:
COV_DETAILS_PATH: ${{github.workspace}}/cov-details
steps:
- uses: actions/checkout@v6.0.3
- uses: actions/checkout@v7.0.0
- name: Setup
run: |
@ -89,13 +89,13 @@ jobs:
id: date
run: echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT
- uses: actions/upload-artifact@v7.0.1
- uses: actions/upload-artifact@v7
with:
name: coverage-${{steps.date.outputs.date}}
path: ${{github.workspace}}/coverage.html
retention-days: 4
- uses: actions/upload-artifact@v7.0.1
- uses: actions/upload-artifact@v7
with:
name: coverage-details-${{steps.date.outputs.date}}
path: ${{env.COV_DETAILS_PATH}}

View file

@ -20,7 +20,7 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Install cross build tools
run: apt update && apt install -y ninja-build cmake python3 g++-13-${{ matrix.arch }}-linux-gnu

File diff suppressed because one or more lines are too long

View file

@ -18,6 +18,7 @@ tools:
bash: [":*"]
safe-outputs:
report-failure-as-issue: false
create-discussion:
title-prefix: "[CSA] "
category: "Agentic Workflows"

View file

@ -21,7 +21,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Go
uses: actions/setup-go@v6
@ -34,7 +34,7 @@ jobs:
python3 mk_go_doc.py --output-dir=api/html/go --go-api-path=../src/api/go
- name: Upload Go Documentation
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: go-docs
path: doc/api/html/go/
@ -46,7 +46,7 @@ jobs:
needs: build-go-docs
steps:
- name: Checkout
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup node
uses: actions/setup-node@v6

View file

@ -56,7 +56,7 @@ jobs:
DISCUSSION_CATEGORY: ${{ github.event.inputs.discussion_category || 'Agentic Workflows' }}
steps:
- name: Checkout Z3
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
with:
ref: ${{ env.Z3_REF }}
fetch-depth: 1
@ -147,7 +147,7 @@ jobs:
- name: Upload generated SMT2 artifact
id: upload_smt2
if: always() && steps.collect_smt2.outputs.has_files == 'true'
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: fstar-generated-smt2-${{ github.run_id }}
path: /tmp/gh-aw/agent/smt2-artifact

File diff suppressed because one or more lines are too long

View file

@ -13,6 +13,7 @@ tools:
toolsets: [default]
safe-outputs:
report-failure-as-issue: false
create-discussion:
title-prefix: "[Issue Backlog] "
category: "Agentic Workflows"

File diff suppressed because one or more lines are too long

View file

@ -31,6 +31,7 @@ tools:
bash: [":*"]
safe-outputs:
report-failure-as-issue: false
mentions: false
allowed-github-references: []
max-bot-mentions: 1

View file

@ -31,7 +31,7 @@ jobs:
ASAN_OPTIONS: "detect_leaks=1:halt_on_error=0:print_stats=1:log_path=/tmp/asan"
steps:
- name: Checkout repository
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -104,7 +104,7 @@ jobs:
- name: Upload ASan reports
if: always()
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: asan-reports
path: /tmp/asan-reports/
@ -121,7 +121,7 @@ jobs:
UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=0:log_path=/tmp/ubsan"
steps:
- name: Checkout repository
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -194,7 +194,7 @@ jobs:
- name: Upload UBSan reports
if: always()
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: ubsan-reports
path: /tmp/ubsan-reports/

View file

@ -14,7 +14,7 @@ jobs:
BUILD_TYPE: Release
steps:
- name: Checkout Repo
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Build
run: |

View file

@ -14,7 +14,7 @@ jobs:
BUILD_TYPE: Release
steps:
- name: Checkout Repo
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Build
run: |

View file

@ -27,7 +27,7 @@ jobs:
timeout-minutes: 30
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup .NET
uses: actions/setup-dotnet@v5
@ -87,7 +87,7 @@ jobs:
timeout-minutes: 30
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup .NET
uses: actions/setup-dotnet@v5
@ -142,7 +142,7 @@ jobs:
timeout-minutes: 30
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup .NET
uses: actions/setup-dotnet@v5
@ -197,7 +197,7 @@ jobs:
timeout-minutes: 30
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup .NET
uses: actions/setup-dotnet@v5
@ -256,7 +256,7 @@ jobs:
timeout-minutes: 30
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Download Windows x64 build from release
env:
@ -292,7 +292,7 @@ jobs:
timeout-minutes: 30
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Download Windows x86 build from release
env:
@ -328,7 +328,7 @@ jobs:
timeout-minutes: 30
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Download Ubuntu x64 build from release
env:
@ -361,7 +361,7 @@ jobs:
timeout-minutes: 30
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Download macOS x64 build from release
env:
@ -394,7 +394,7 @@ jobs:
timeout-minutes: 30
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Download macOS ARM64 build from release
env:
@ -431,7 +431,7 @@ jobs:
timeout-minutes: 60
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -470,7 +470,7 @@ jobs:
timeout-minutes: 60
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -510,7 +510,7 @@ jobs:
timeout-minutes: 60
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -553,7 +553,7 @@ jobs:
timeout-minutes: 30
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -582,7 +582,7 @@ jobs:
timeout-minutes: 30
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -611,7 +611,7 @@ jobs:
timeout-minutes: 30
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -640,7 +640,7 @@ jobs:
timeout-minutes: 30
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -672,7 +672,7 @@ jobs:
timeout-minutes: 30
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -727,7 +727,7 @@ jobs:
timeout-minutes: 30
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Download macOS x64 build from release
env:
@ -779,7 +779,7 @@ jobs:
timeout-minutes: 30
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Download macOS ARM64 build from release
env:
@ -835,7 +835,7 @@ jobs:
timeout-minutes: 10
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -844,3 +844,97 @@ jobs:
- name: Run build script unit tests
run: python -m unittest discover -s scripts/tests -p "test_*.py" -v
# ============================================================================
# DOTNET MANAGED WRAPPER ARCHITECTURE VALIDATION
# ============================================================================
validate-dotnet-anycpu:
name: "Validate Microsoft.Z3.dll is AnyCPU (issue #9863)"
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch' }}
timeout-minutes: 15
steps:
- name: Checkout code
uses: actions/checkout@v7.0.0
- name: Download NuGet package from release
env:
GH_TOKEN: ${{ github.token }}
run: |
TAG="${{ github.event.inputs.release_tag }}"
if [ -z "$TAG" ]; then
TAG="Nightly"
fi
gh release download $TAG --pattern "*.nupkg" --dir nuget-packages
- name: Extract managed DLL from NuGet package
run: |
# NuGet packages are ZIP archives; exclude the symbols package
NUPKG=$(ls nuget-packages/*.nupkg | grep -v '\.symbols\.' | grep -v '\.snupkg' | head -n 1)
echo "Checking package: $NUPKG"
unzip -q "$NUPKG" "lib/netstandard2.0/Microsoft.Z3.dll" -d nupkg-extracted
- name: Check PE Machine field is AnyCPU (not architecture-specific)
run: |
python3 - <<'EOF'
import struct
import sys
dll_path = "nupkg-extracted/lib/netstandard2.0/Microsoft.Z3.dll"
with open(dll_path, 'rb') as f:
# Verify MZ magic
if f.read(2) != b'MZ':
print("ERROR: Not a valid PE file (missing MZ header)")
sys.exit(1)
# Read PE header offset stored at 0x3C in the DOS stub
f.seek(0x3C)
pe_offset = struct.unpack('<I', f.read(4))[0]
# Verify PE signature
f.seek(pe_offset)
if f.read(4) != b'PE\x00\x00':
print("ERROR: Missing PE\\0\\0 signature")
sys.exit(1)
# COFF Machine field is the 2 bytes immediately after the PE signature
machine = struct.unpack('<H', f.read(2))[0]
machine_names = {
0x0000: "Unknown/AnyCPU",
0x014C: "i386 (AnyCPU for managed assemblies)",
0x8664: "AMD64/x64",
0xAA64: "ARM64",
0x01C0: "ARM",
0x01C4: "ARM Thumb-2",
}
machine_name = machine_names.get(machine, f"0x{machine:04X}")
print(f"Machine field: 0x{machine:04X} = {machine_name}")
if machine == 0x8664:
print()
print("FAIL: Machine is AMD64 (0x8664).")
print("This prevents loading on arm64 .NET hosts even though the assembly")
print("contains only pure IL (CorFlags.ILONLY=True).")
print("The DLL must be built as AnyCPU (Machine=0x014C) so the CLR loader")
print("accepts it on every host architecture.")
print("See issue #9863 for details.")
sys.exit(1)
elif machine == 0xAA64:
print()
print("FAIL: Machine is ARM64 (0xAA64).")
print("This prevents loading on x64 .NET hosts.")
print("The DLL must be built as AnyCPU (Machine=0x014C).")
sys.exit(1)
elif machine in (0x014C, 0x0000):
print()
print("PASS: Machine field indicates AnyCPU.")
print("Microsoft.Z3.dll will load on any .NET host architecture.")
else:
print()
print(f"FAIL: Unexpected Machine field 0x{machine:04X}.")
print("Expected 0x014C (i386/AnyCPU) for a managed-only assembly.")
sys.exit(1)
EOF

View file

@ -35,7 +35,7 @@ jobs:
timeout-minutes: 90
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -59,7 +59,7 @@ jobs:
echo "OK: macOS x64 artifacts are x86_64"
- name: Upload artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: macOsBuild
path: dist/*.zip
@ -71,7 +71,7 @@ jobs:
timeout-minutes: 90
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -95,7 +95,7 @@ jobs:
echo "OK: macOS arm64 artifacts are arm64"
- name: Upload artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: MacArm64
path: dist/*.zip
@ -112,7 +112,7 @@ jobs:
timeout-minutes: 15
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Download macOS x64 Build
uses: actions/download-artifact@v8.0.1
@ -171,7 +171,7 @@ jobs:
timeout-minutes: 15
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Download macOS ARM64 Build
uses: actions/download-artifact@v8.0.1
@ -229,7 +229,7 @@ jobs:
timeout-minutes: 90
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -246,7 +246,7 @@ jobs:
run: python z3test/scripts/test_benchmarks.py build-dist/z3 z3test/regressions/smt2
- name: Upload artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: UbuntuBuild
path: dist/*.zip
@ -258,7 +258,7 @@ jobs:
timeout-minutes: 90
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -281,7 +281,7 @@ jobs:
python scripts/mk_unix_dist.py --nodotnet --arch=arm64
- name: Upload artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: UbuntuArm64
path: dist/*.zip
@ -293,7 +293,7 @@ jobs:
timeout-minutes: 90
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -336,7 +336,7 @@ jobs:
run: zip -r z3doc.zip doc/api
- name: Upload artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: UbuntuDoc
path: z3doc.zip
@ -349,7 +349,7 @@ jobs:
container: quay.io/pypa/manylinux_2_28_x86_64:latest
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Select Python
run: |
@ -374,7 +374,7 @@ jobs:
run: pip install ./src/api/python/wheelhouse/*.whl && python - <src/api/python/z3test.py z3 && python - <src/api/python/z3test.py z3num
- name: Upload artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: ManyLinuxPythonBuildAMD64
path: src/api/python/wheelhouse/*.whl
@ -387,7 +387,7 @@ jobs:
container: quay.io/pypa/manylinux_2_28_x86_64:latest
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Download ARM toolchain
run: curl -L -o /tmp/arm-toolchain.tar.xz 'https://developer.arm.com/-/media/Files/downloads/gnu/13.3.rel1/binrel/arm-gnu-toolchain-13.3.rel1-x86_64-aarch64-none-linux-gnu.tar.xz'
@ -422,7 +422,7 @@ jobs:
run: cd src/api/python && CC=aarch64-none-linux-gnu-gcc CXX=aarch64-none-linux-gnu-g++ AR=aarch64-none-linux-gnu-ar LD=aarch64-none-linux-gnu-ld Z3_CROSS_COMPILING=aarch64 python -m build && AUDITWHEEL_PLAT= auditwheel repair --best-plat dist/*.whl && cd ../../..
- name: Upload artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: ManyLinuxPythonBuildArm64
path: src/api/python/wheelhouse/*.whl
@ -435,7 +435,7 @@ jobs:
container: quay.io/pypa/manylinux_2_28_x86_64:latest
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Download RISC-V toolchain
run: curl -L -o /tmp/riscv-toolchain.tar.gz 'https://github.com/riscv-collab/riscv-gnu-toolchain/releases/download/2024.09.03/riscv64-glibc-ubuntu-20.04-gcc-nightly-2024.09.03-nightly.tar.gz'
@ -477,7 +477,7 @@ jobs:
run: cd src/api/python && CC=riscv64-unknown-linux-gnu-gcc CXX=riscv64-unknown-linux-gnu-g++ AR=riscv64-unknown-linux-gnu-ar LD=riscv64-unknown-linux-gnu-ld Z3_CROSS_COMPILING=riscv64 python -m build && AUDITWHEEL_PLAT= auditwheel repair --best-plat dist/*.whl && cd ../../..
- name: Upload artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: ManyLinuxPythonBuildRiscv64
path: src/api/python/wheelhouse/*.whl
@ -489,7 +489,7 @@ jobs:
timeout-minutes: 90
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup packages
run: sudo apt-get update && sudo apt-get install -y python3-dev python3-pip python3-venv
@ -512,11 +512,10 @@ jobs:
run: |
source ~/emsdk/emsdk_env.sh
cd src/api/python
CFLAGS="${CFLAGS}" LDFLAGS="${LDFLAGS}" CXXFLAGS="${CXXFLAGS}" ~/env/bin/pyodide build --exports whole_archive
env:
CFLAGS: "-fexceptions -s DISABLE_EXCEPTION_CATCHING=0 -g2"
LDFLAGS: "-fexceptions -s WASM_BIGINT"
CXXFLAGS: "-fexceptions -s DISABLE_EXCEPTION_CATCHING=0"
# Exception/longjmp/bigint flags are declared in pyproject.toml and
# combined with Pyodide's -fwasm-exceptions defaults. Passing the
# legacy JS-EH -fexceptions flags here conflicts with the wasm-EH ABI.
~/env/bin/pyodide build --exports whole_archive
- name: Setup env-pyodide
run: |
@ -530,7 +529,7 @@ jobs:
~/env-pyodide/bin/python src/api/python/z3test.py z3
- name: Upload artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: PyodidePythonBuild
path: src/api/python/dist/*.whl
@ -542,7 +541,7 @@ jobs:
timeout-minutes: 120
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -552,11 +551,12 @@ jobs:
- name: Build
shell: cmd
run: |
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
for /f "usebackq delims=" %%i in (`"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest -prerelease -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do set "VSPATH=%%i"
call "%VSPATH%\VC\Auxiliary\Build\vcvarsall.bat" x64 || exit /b 1
python scripts\mk_win_dist.py --x64-only --dotnet-key=%GITHUB_WORKSPACE%\resources\z3.snk --zip
- name: Upload artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: WindowsBuild-x64
path: dist/*.zip
@ -568,7 +568,7 @@ jobs:
timeout-minutes: 120
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -578,11 +578,12 @@ jobs:
- name: Build
shell: cmd
run: |
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x86
for /f "usebackq delims=" %%i in (`"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest -prerelease -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do set "VSPATH=%%i"
call "%VSPATH%\VC\Auxiliary\Build\vcvarsall.bat" x86 || exit /b 1
python scripts\mk_win_dist.py --x86-only --dotnet-key=%GITHUB_WORKSPACE%\resources\z3.snk --zip
- name: Upload artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: WindowsBuild-x86
path: dist/*.zip
@ -594,7 +595,7 @@ jobs:
timeout-minutes: 90
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -604,11 +605,12 @@ jobs:
- name: Build
shell: cmd
run: |
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" amd64_arm64
for /f "usebackq delims=" %%i in (`"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest -prerelease -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do set "VSPATH=%%i"
call "%VSPATH%\VC\Auxiliary\Build\vcvarsall.bat" amd64_arm64 || exit /b 1
python scripts\mk_win_dist_cmake.py --arm64-only --dotnet-key=%GITHUB_WORKSPACE%\resources\z3.snk --assembly-version=${{ env.MAJOR }}.${{ env.MINOR }}.${{ env.PATCH }} --zip
- name: Upload artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: WindowsBuild-arm64
path: dist/arm64/*.zip
@ -624,7 +626,7 @@ jobs:
runs-on: windows-latest
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -685,7 +687,7 @@ jobs:
nuget pack out\Microsoft.Z3.sym.nuspec -Version ${{ env.MAJOR }}.${{ env.MINOR }}.${{ env.PATCH }}.${{ github.run_number }} -OutputDirectory . -Verbosity detailed -Symbols -SymbolPackageFormat snupkg -BasePath out
- name: Upload artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: NuGet
path: |
@ -699,7 +701,7 @@ jobs:
runs-on: windows-latest
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -730,7 +732,7 @@ jobs:
nuget pack out\Microsoft.Z3.x86.sym.nuspec -Version ${{ env.MAJOR }}.${{ env.MINOR }}.${{ env.PATCH }}.${{ github.run_number }} -OutputDirectory . -Verbosity detailed -Symbols -SymbolPackageFormat snupkg -BasePath out
- name: Upload artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: NuGet32
path: |
@ -744,7 +746,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -835,7 +837,7 @@ jobs:
cp artifacts/*.whl src/api/python/dist/.
- name: Upload artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: PythonPackages
path: src/api/python/dist/*
@ -865,7 +867,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Download all artifacts
uses: actions/download-artifact@v8.0.1

View file

@ -20,7 +20,7 @@ jobs:
runs-on: windows-latest
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -30,11 +30,12 @@ jobs:
- name: Build Windows x64
shell: cmd
run: |
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
for /f "usebackq delims=" %%i in (`"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest -prerelease -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do set "VSPATH=%%i"
call "%VSPATH%\VC\Auxiliary\Build\vcvarsall.bat" x64 || exit /b 1
python scripts\mk_win_dist.py --x64-only --dotnet-key=%GITHUB_WORKSPACE%\resources\z3.snk --assembly-version=${{ github.event.inputs.version || '4.17.0' }} --zip
- name: Upload Windows x64 artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: windows-x64
path: dist/*.zip
@ -44,7 +45,7 @@ jobs:
runs-on: windows-latest
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -54,11 +55,12 @@ jobs:
- name: Build Windows x86
shell: cmd
run: |
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x86
for /f "usebackq delims=" %%i in (`"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest -prerelease -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do set "VSPATH=%%i"
call "%VSPATH%\VC\Auxiliary\Build\vcvarsall.bat" x86 || exit /b 1
python scripts\mk_win_dist.py --x86-only --dotnet-key=%GITHUB_WORKSPACE%\resources\z3.snk --assembly-version=${{ github.event.inputs.version || '4.17.0' }} --zip
- name: Upload Windows x86 artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: windows-x86
path: dist/*.zip
@ -68,7 +70,7 @@ jobs:
runs-on: windows-latest
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -78,11 +80,12 @@ jobs:
- name: Build Windows ARM64
shell: cmd
run: |
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" amd64_arm64
for /f "usebackq delims=" %%i in (`"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest -prerelease -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do set "VSPATH=%%i"
call "%VSPATH%\VC\Auxiliary\Build\vcvarsall.bat" amd64_arm64 || exit /b 1
python scripts\mk_win_dist_cmake.py --arm64-only --dotnet-key=%GITHUB_WORKSPACE%\resources\z3.snk --assembly-version=${{ github.event.inputs.version || '4.17.0' }} --zip
- name: Upload Windows ARM64 artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: windows-arm64
path: build-dist\arm64\dist\*.zip
@ -92,7 +95,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -103,7 +106,7 @@ jobs:
run: python scripts/mk_unix_dist.py --dotnet-key=$GITHUB_WORKSPACE/resources/z3.snk
- name: Upload Ubuntu artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: ubuntu
path: dist/*.zip
@ -113,7 +116,7 @@ jobs:
runs-on: macos-14
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -124,7 +127,7 @@ jobs:
run: python scripts/mk_unix_dist.py --dotnet-key=$GITHUB_WORKSPACE/resources/z3.snk
- name: Upload macOS x64 artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: macos-x64
path: dist/*.zip
@ -134,7 +137,7 @@ jobs:
runs-on: macos-14
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -145,7 +148,7 @@ jobs:
run: python scripts/mk_unix_dist.py --dotnet-key=$GITHUB_WORKSPACE/resources/z3.snk --arch=arm64
- name: Upload macOS ARM64 artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: macos-arm64
path: dist/*.zip
@ -157,7 +160,7 @@ jobs:
runs-on: windows-latest
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -198,7 +201,7 @@ jobs:
nuget pack out\Microsoft.Z3.sym.nuspec -OutputDirectory . -Verbosity detailed -Symbols -SymbolPackageFormat snupkg -BasePath out
- name: Upload NuGet package
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: nuget-x64
path: |
@ -212,7 +215,7 @@ jobs:
runs-on: windows-latest
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -247,7 +250,7 @@ jobs:
nuget pack out\Microsoft.Z3.x86.sym.nuspec -OutputDirectory . -Verbosity detailed -Symbols -SymbolPackageFormat snupkg -BasePath out
- name: Upload NuGet package
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: nuget-x86
path: |

View file

@ -17,7 +17,7 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
# Cache ccache (shared across runs)
- name: Cache ccache

File diff suppressed because one or more lines are too long

View file

@ -19,6 +19,7 @@ tools:
toolsets: [default]
safe-outputs:
report-failure-as-issue: false
create-discussion:
title-prefix: "[Ostrich Benchmark] "
category: "Agentic Workflows"

57
.github/workflows/pyodide-pypi.yml vendored Normal file
View file

@ -0,0 +1,57 @@
name: Pyodide Wheel (PyPI)
# Builds a PEP 783 `pyemscripten_*_wasm32` wheel for z3-solver using cibuildwheel
# and publishes it to PyPI on tag pushes. Unlike the legacy pyodide.yml (which
# uses `pyodide build` and produces a Pyodide-version-locked emscripten_* wheel
# uploaded only as a CI artifact), this wheel is installable at runtime with
# micropip from PyPI. See src/api/python/pyproject.toml [tool.cibuildwheel].
on:
release:
types: [created]
workflow_dispatch:
permissions:
contents: read
jobs:
build-pyodide:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v7.0.0
- name: Build Pyodide wheel
uses: pypa/cibuildwheel@v4.1.0
with:
# The Python bindings live in a subdirectory of the repo.
package-dir: src/api/python
env:
CIBW_PLATFORM: pyodide
# Exception/longjmp/bigint flags are declared in
# src/api/python/pyproject.toml ([tool.pyodide.build]) and combined
# with Pyodide's -fwasm-exceptions defaults. Don't set CFLAGS/CXXFLAGS
# here — a JS-EH -fexceptions value conflicts with the wasm-EH ABI.
- name: Store Pyodide wheel
uses: actions/upload-artifact@v7
with:
name: pyodide-wheel
path: wheelhouse/*.whl
publish:
name: Publish to PyPI
runs-on: ubuntu-24.04
if: startsWith(github.ref, 'refs/tags/')
needs: [build-pyodide]
environment: release
permissions:
id-token: write # trusted publishing (OIDC), no API token needed
steps:
- name: Download Pyodide wheel
uses: actions/download-artifact@v8
with:
name: pyodide-wheel
path: dist/
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1

View file

@ -20,7 +20,7 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup packages
run: sudo apt-get update && sudo apt-get install -y python3-dev python3-pip python3-venv
@ -42,11 +42,10 @@ jobs:
run: |
source ~/emsdk/emsdk_env.sh
cd src/api/python
CFLAGS="${CFLAGS}" LDFLAGS="${LDFLAGS}" CXXFLAG="${CXXFLAGS}" ~/env/bin/pyodide build --exports whole_archive
env:
CFLAGS: "-fexceptions -s DISABLE_EXCEPTION_CATCHING=0 -g2"
LDFLAGS: "-fexceptions -s WASM_BIGINT"
CXXFLAGS: "-fexceptions -s DISABLE_EXCEPTION_CATCHING=0"
# Exception/longjmp/bigint flags are declared in pyproject.toml and
# combined with Pyodide's -fwasm-exceptions defaults. Passing the
# legacy JS-EH -fexceptions flags here conflicts with the wasm-EH ABI.
~/env/bin/pyodide build --exports whole_archive
- name: Setup env-pyodide
run: |
@ -65,4 +64,3 @@ jobs:
name: pyodide-wheel
path: src/api/python/dist/*.whl
retention-days: 1

File diff suppressed because one or more lines are too long

View file

@ -16,6 +16,7 @@ tools:
toolsets: [default]
safe-outputs:
report-failure-as-issue: false
create-discussion:
title-prefix: "[QF_S Benchmark] "
category: "Agentic Workflows"

File diff suppressed because one or more lines are too long

View file

@ -18,6 +18,7 @@ tools:
edit: {}
safe-outputs:
report-failure-as-issue: false
create-discussion:
title-prefix: "[Release Notes] "
category: "Announcements"

View file

@ -36,7 +36,7 @@ jobs:
timeout-minutes: 90
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -66,7 +66,7 @@ jobs:
run: python z3test/scripts/test_benchmarks.py build-dist/z3 z3test/regressions/smt2
- name: Upload artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: macOsBuild
path: dist/*.zip
@ -78,7 +78,7 @@ jobs:
timeout-minutes: 90
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -105,7 +105,7 @@ jobs:
run: git clone https://github.com/z3prover/z3test z3test
- name: Upload artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: MacArm64
path: dist/*.zip
@ -122,7 +122,7 @@ jobs:
timeout-minutes: 15
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Download macOS x64 Build
uses: actions/download-artifact@v8.0.1
@ -181,7 +181,7 @@ jobs:
timeout-minutes: 15
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Download macOS ARM64 Build
uses: actions/download-artifact@v8.0.1
@ -239,7 +239,7 @@ jobs:
timeout-minutes: 90
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -256,7 +256,7 @@ jobs:
run: python z3test/scripts/test_benchmarks.py build-dist/z3 z3test/regressions/smt2
- name: Upload artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: UbuntuBuild
path: dist/*.zip
@ -268,7 +268,7 @@ jobs:
timeout-minutes: 90
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -291,7 +291,7 @@ jobs:
python scripts/mk_unix_dist.py --nodotnet --arch=arm64
- name: Upload artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: UbuntuArm64
path: dist/*.zip
@ -303,7 +303,7 @@ jobs:
timeout-minutes: 90
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -346,7 +346,7 @@ jobs:
run: zip -r z3doc.zip doc/api
- name: Upload artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: UbuntuDoc
path: z3doc.zip
@ -359,7 +359,7 @@ jobs:
container: quay.io/pypa/manylinux_2_28_x86_64:latest
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Select Python
run: |
@ -384,7 +384,7 @@ jobs:
run: pip install ./src/api/python/wheelhouse/*.whl && python - <src/api/python/z3test.py z3 && python - <src/api/python/z3test.py z3num
- name: Upload artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: ManyLinuxPythonBuildAMD64
path: src/api/python/wheelhouse/*.whl
@ -397,7 +397,7 @@ jobs:
container: quay.io/pypa/manylinux_2_28_x86_64:latest
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Download ARM toolchain
run: curl -L -o /tmp/arm-toolchain.tar.xz 'https://developer.arm.com/-/media/Files/downloads/gnu/13.3.rel1/binrel/arm-gnu-toolchain-13.3.rel1-x86_64-aarch64-none-linux-gnu.tar.xz'
@ -432,7 +432,7 @@ jobs:
run: cd src/api/python && CC=aarch64-none-linux-gnu-gcc CXX=aarch64-none-linux-gnu-g++ AR=aarch64-none-linux-gnu-ar LD=aarch64-none-linux-gnu-ld Z3_CROSS_COMPILING=aarch64 python -m build && AUDITWHEEL_PLAT= auditwheel repair --best-plat dist/*.whl && cd ../../..
- name: Upload artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: ManyLinuxPythonBuildArm64
path: src/api/python/wheelhouse/*.whl
@ -445,7 +445,7 @@ jobs:
container: quay.io/pypa/manylinux_2_28_x86_64:latest
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Download RISC-V toolchain
run: curl -L -o /tmp/riscv-toolchain.tar.gz 'https://github.com/riscv-collab/riscv-gnu-toolchain/releases/download/2024.09.03/riscv64-glibc-ubuntu-20.04-gcc-nightly-2024.09.03-nightly.tar.gz'
@ -487,7 +487,7 @@ jobs:
run: cd src/api/python && CC=riscv64-unknown-linux-gnu-gcc CXX=riscv64-unknown-linux-gnu-g++ AR=riscv64-unknown-linux-gnu-ar LD=riscv64-unknown-linux-gnu-ld Z3_CROSS_COMPILING=riscv64 python -m build && AUDITWHEEL_PLAT= auditwheel repair --best-plat dist/*.whl && cd ../../..
- name: Upload artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: ManyLinuxPythonBuildRiscv64
path: src/api/python/wheelhouse/*.whl
@ -499,7 +499,7 @@ jobs:
timeout-minutes: 90
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup packages
run: sudo apt-get update && sudo apt-get install -y python3-dev python3-pip python3-venv
@ -522,11 +522,10 @@ jobs:
run: |
source ~/emsdk/emsdk_env.sh
cd src/api/python
CFLAGS="${CFLAGS}" LDFLAGS="${LDFLAGS}" CXXFLAGS="${CXXFLAGS}" ~/env/bin/pyodide build --exports whole_archive
env:
CFLAGS: "-fexceptions -s DISABLE_EXCEPTION_CATCHING=0 -g2"
LDFLAGS: "-fexceptions -s WASM_BIGINT"
CXXFLAGS: "-fexceptions -s DISABLE_EXCEPTION_CATCHING=0"
# Exception/longjmp/bigint flags are declared in pyproject.toml and
# combined with Pyodide's -fwasm-exceptions defaults. Passing the
# legacy JS-EH -fexceptions flags here conflicts with the wasm-EH ABI.
~/env/bin/pyodide build --exports whole_archive
- name: Setup env-pyodide
run: |
@ -540,7 +539,7 @@ jobs:
~/env-pyodide/bin/python src/api/python/z3test.py z3
- name: Upload artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: PyodidePythonBuild
path: src/api/python/dist/*.whl
@ -552,7 +551,7 @@ jobs:
timeout-minutes: 120
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -562,11 +561,12 @@ jobs:
- name: Build
shell: cmd
run: |
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
for /f "usebackq delims=" %%i in (`"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest -prerelease -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do set "VSPATH=%%i"
call "%VSPATH%\VC\Auxiliary\Build\vcvarsall.bat" x64 || exit /b 1
python scripts\mk_win_dist.py --x64-only --dotnet-key=%GITHUB_WORKSPACE%\resources\z3.snk --zip
- name: Upload artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: WindowsBuild-x64
path: dist/*.zip
@ -578,7 +578,7 @@ jobs:
timeout-minutes: 120
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -588,11 +588,12 @@ jobs:
- name: Build
shell: cmd
run: |
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x86
for /f "usebackq delims=" %%i in (`"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest -prerelease -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do set "VSPATH=%%i"
call "%VSPATH%\VC\Auxiliary\Build\vcvarsall.bat" x86 || exit /b 1
python scripts\mk_win_dist.py --x86-only --dotnet-key=%GITHUB_WORKSPACE%\resources\z3.snk --zip
- name: Upload artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: WindowsBuild-x86
path: dist/*.zip
@ -604,7 +605,7 @@ jobs:
timeout-minutes: 90
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -614,11 +615,12 @@ jobs:
- name: Build
shell: cmd
run: |
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" amd64_arm64
for /f "usebackq delims=" %%i in (`"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest -prerelease -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do set "VSPATH=%%i"
call "%VSPATH%\VC\Auxiliary\Build\vcvarsall.bat" amd64_arm64 || exit /b 1
python scripts\mk_win_dist_cmake.py --arm64-only --dotnet-key=%GITHUB_WORKSPACE%\resources\z3.snk --assembly-version=${{ env.RELEASE_VERSION }} --zip
- name: Upload artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: WindowsBuild-arm64
path: dist/arm64/*.zip
@ -634,7 +636,7 @@ jobs:
runs-on: windows-latest
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -695,7 +697,7 @@ jobs:
nuget pack out\Microsoft.Z3.sym.nuspec -OutputDirectory . -Verbosity detailed -Symbols -SymbolPackageFormat snupkg -BasePath out
- name: Upload artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: NuGet
path: |
@ -709,7 +711,7 @@ jobs:
runs-on: windows-latest
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -740,7 +742,7 @@ jobs:
nuget pack out\Microsoft.Z3.x86.sym.nuspec -OutputDirectory . -Verbosity detailed -Symbols -SymbolPackageFormat snupkg -BasePath out
- name: Upload artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: NuGet32
path: |
@ -754,7 +756,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup Python
uses: actions/setup-python@v6
@ -842,7 +844,7 @@ jobs:
cp artifacts/*.whl src/api/python/dist/.
- name: Upload artifact
uses: actions/upload-artifact@v7.0.1
uses: actions/upload-artifact@v7
with:
name: PythonPackage
path: src/api/python/dist/*
@ -873,7 +875,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Download all artifacts
uses: actions/download-artifact@v8.0.1
@ -929,7 +931,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Download NuGet packages
uses: actions/download-artifact@v8.0.1

File diff suppressed because one or more lines are too long

View file

@ -30,6 +30,7 @@ tools:
bash: [":*"]
safe-outputs:
report-failure-as-issue: false
mentions: false
allowed-github-references: []
max-bot-mentions: 1

File diff suppressed because one or more lines are too long

View file

@ -20,6 +20,7 @@ tools:
edit: {}
safe-outputs:
report-failure-as-issue: false
create-discussion:
title-prefix: "[Specbot] "
category: "Agentic Workflows"

File diff suppressed because one or more lines are too long

View file

@ -21,6 +21,7 @@ tools:
bash: [":*"]
safe-outputs:
report-failure-as-issue: false
create-issue:
labels:
- enhancement

File diff suppressed because one or more lines are too long

View file

@ -23,6 +23,7 @@ tools:
toolsets: [default]
safe-outputs:
report-failure-as-issue: false
create-discussion:
title-prefix: "[TPTP Benchmark] "
category: "Agentic Workflows"

View file

@ -21,7 +21,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup node
uses: actions/setup-node@v6

View file

@ -21,7 +21,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6.0.3
uses: actions/checkout@v7.0.0
- name: Setup node
uses: actions/setup-node@v6

View file

@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6.0.3
- uses: actions/checkout@v7.0.0
- name: Configure CMake
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}

File diff suppressed because one or more lines are too long

View file

@ -17,6 +17,7 @@ tools:
bash: [":*"]
safe-outputs:
report-failure-as-issue: false
create-discussion:
title-prefix: "[Workflow Suggestions] "
category: "Agentic Workflows"

File diff suppressed because one or more lines are too long

View file

@ -27,6 +27,7 @@ tools:
- "clang-format:*"
safe-outputs:
report-failure-as-issue: false
create-issue:
title-prefix: "[zipt-review] "
labels: [code-quality, automated, string-solver]

View file

@ -19,14 +19,23 @@ filegroup(
cmake(
name = "z3_dynamic",
generate_args = [
"-G Ninja",
"-G Ninja",
"-D Z3_EXPORTED_TARGETS=", # prevents installation, leaving symlinks between dylibs intact on copy
],
lib_source = ":all_files",
out_binaries = ["z3"],
out_shared_libs = select({
"@platforms//os:linux": ["libz3.so"],
# "@platforms//os:osx": ["libz3.dylib"], # FIXME: this is not working, libz3<version>.dylib is not copied
# NOTE: These will need to be manually bumped along side the version in MODULE.bazel/VERSION.txt/CMake
"@platforms//os:linux": [
"libz3.so",
"libz3.so.4.17",
"libz3.so.4.17.0.0",
],
"@platforms//os:osx": [
"libz3.dylib",
"libz3.4.17.dylib",
"libz3.4.17.0.0.dylib",
],
"@platforms//os:windows": ["libz3.dll"],
"//conditions:default": ["@platforms//:incompatible"],
}),
@ -36,7 +45,7 @@ cmake(
cmake(
name = "z3_static",
generate_args = [
"-G Ninja",
"-G Ninja",
"-D BUILD_SHARED_LIBS=OFF",
"-D Z3_BUILD_LIBZ3_SHARED=OFF",
],

View file

@ -204,7 +204,12 @@ elseif (EMSCRIPTEN)
"-Os"
"-s ALLOW_MEMORY_GROWTH=1"
"-s ASSERTIONS=0"
"-s DISABLE_EXCEPTION_CATCHING=0"
# Use native wasm exception handling + wasm longjmp to match the ABI of the
# Pyodide / modern-emscripten main module. The legacy JS-based EH (which the
# removed "-s DISABLE_EXCEPTION_CATCHING=0" selected) makes libz3 import
# invoke_* trampolines the Pyodide runtime no longer provides.
"-fwasm-exceptions"
"-s SUPPORT_LONGJMP=wasm"
"-s ERROR_ON_UNDEFINED_SYMBOLS=1"
)
endif()

View file

@ -9,9 +9,20 @@ set(GCC_ONLY_WARNINGS "")
# Disable C++98 compatibility warnings to prevent excessive warning output
# when building with clang-cl or when -Weverything is enabled.
# These warnings are not useful for Z3 since it requires C++20.
#
# The "-Wno-zero-length-array" is for cases where Z3 is fetched by a CMake build
# to serve as a component in another system. Z3 has many classes whose last member
# is a zero-length array of some type T, indicating a variable-length array of T.
# If the including system compiles with "-Wzero-length-array", there will be
# many warnings. Overriding this prevents such warnings in the Z3 portion of the
# build of the including system.
set(CLANG_ONLY_WARNINGS
"-Wno-c++98-compat"
"-Wno-c++98-compat-pedantic"
"-Wno-zero-length-array"
"-Wc99-extensions"
"-Wsuggest-override"
"-Winconsistent-missing-override"
)
set(MSVC_WARNINGS "/W3")

View file

@ -1804,6 +1804,7 @@ class DotNetDLLComponent(Component):
<Description>Z3 is a satisfiability modulo theories solver from Microsoft Research.</Description>
<Copyright>Copyright Microsoft Corporation. All rights reserved.</Copyright>
<PackageTags>smt constraint solver theorem prover</PackageTags>
<PlatformTarget>AnyCPU</PlatformTarget>
%s
</PropertyGroup>

View file

@ -18,13 +18,13 @@
double ackr_helper::calculate_lemma_bound(fun2terms_map const& occs1, sel2terms_map const& occs2) {
double total = 0;
for (auto const& kv : occs1) {
total += n_choose_2_chk(kv.m_value->var_args.size());
total += kv.m_value->const_args.size() * kv.m_value->var_args.size();
for (auto const &[k, v] : occs1) {
total += n_choose_2_chk(v->var_args.size());
total += v->const_args.size() * v->var_args.size();
}
for (auto const& kv : occs2) {
total += n_choose_2_chk(kv.m_value->var_args.size());
total += kv.m_value->const_args.size() * kv.m_value->var_args.size();
for (auto const &[k, v] : occs2) {
total += n_choose_2_chk(v->var_args.size());
total += v->const_args.size() * v->var_args.size();
}
return total;
}

View file

@ -52,14 +52,26 @@ public:
return m_autil.is_select(a) && is_uninterp_const(a->get_arg(0));
}
void mark_non_select_rec(expr* t, expr_mark& visited, expr_mark& non_select) {
if (visited.is_marked(t))
return;
visited.mark(t, true);
non_select.mark(t, true);
if (is_app(t)) {
for (expr *arg : *to_app(t))
mark_non_select_rec(arg, visited,non_select);
}
}
void mark_non_select(app* a, expr_mark& non_select) {
if (m_autil.is_select(a)) {
bool first = true;
expr_mark visited;
for (expr* arg : *a) {
if (first)
first = false;
else
non_select.mark(arg, true);
mark_non_select_rec(arg, visited, non_select);
}
}
else {
@ -70,10 +82,10 @@ public:
void prune_non_select(obj_map<app, app_set*> & sels, expr_mark& non_select) {
ptr_vector<app> nons;
for (auto& kv : sels) {
if (non_select.is_marked(kv.m_key)) {
nons.push_back(kv.m_key);
dealloc(kv.m_value);
for (auto &[k, v] : sels) {
if (non_select.is_marked(k)) {
nons.push_back(k);
dealloc(v);
}
}
for (app* s : nons) {

View file

@ -149,9 +149,9 @@ void lackr::eager_enc() {
checkpoint();
ackr(v);
}
for (auto const& kv : m_sel2terms) {
for (auto const &[k, v] : m_sel2terms) {
checkpoint();
ackr(kv.get_value());
ackr(v);
}
}
@ -190,13 +190,13 @@ void lackr::abstract_fun(fun2terms_map const& apps) {
}
void lackr::abstract_sel(sel2terms_map const& apps) {
for (auto const& kv : apps) {
func_decl * fd = kv.m_key->get_decl();
for (app * t : kv.m_value->const_args) {
for (auto const &[k, v] : apps) {
func_decl * fd = k->get_decl();
for (app * t : v->const_args) {
app * fc = m.mk_fresh_const(fd->get_name(), t->get_sort());
m_info->set_abstr(t, fc);
}
for (app * t : kv.m_value->var_args) {
for (app * t : v->var_args) {
app * fc = m.mk_fresh_const(fd->get_name(), t->get_sort());
m_info->set_abstr(t, fc);
}

View file

@ -60,6 +60,7 @@
<Warn>4</Warn>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<DocumentationFile>$(OutputPath)\Microsoft.Z3.xml</DocumentationFile>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<!-- Compilation items -->

View file

@ -5400,10 +5400,20 @@
"dev": true
},
"node_modules/linkify-it": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz",
"integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==",
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.1.tgz",
"integrity": "sha512-wVoTjP4Q6R0NW5hiZkVJaFZPWgtXfoGF+6LucL3/FtiNjmcHhYjEr5f1Kqjirc1nBW07J/ZuRFumqr2oqccEWg==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/puzrin"
},
{
"type": "github",
"url": "https://github.com/sponsors/markdown-it"
}
],
"license": "MIT",
"dependencies": {
"uc.micro": "^2.0.0"
@ -5501,15 +5511,25 @@
}
},
"node_modules/markdown-it": {
"version": "14.1.0",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz",
"integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==",
"version": "14.2.0",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.2.0.tgz",
"integrity": "sha512-1TGiQiJVRQ3NPmZH6sx5Cfnmg6GQm9jvC1ch4TK511NjSJvjzKLzn5pPfZRNZkRPZP0HqCioSndqH8v2nRaWVQ==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/puzrin"
},
{
"type": "github",
"url": "https://github.com/sponsors/markdown-it"
}
],
"license": "MIT",
"dependencies": {
"argparse": "^2.0.1",
"entities": "^4.4.0",
"linkify-it": "^5.0.0",
"linkify-it": "^5.0.1",
"mdurl": "^2.0.0",
"punycode.js": "^2.3.1",
"uc.micro": "^2.1.0"

View file

@ -1,3 +1,29 @@
[build-system]
requires = ["setuptools>=70"]
build-backend = "setuptools.build_meta"
# --- Pyodide / WebAssembly (PEP 783) build configuration ---------------------
# Consumed by pyodide-build (invoked directly or via `cibuildwheel --platform
# pyodide`). These flags are forwarded to the emscripten toolchain that compiles
# libz3 to wasm32. setup.py's IS_PYODIDE branch appends the same -fexceptions
# flags defensively, but declaring them here is what cibuildwheel relies on.
# Pyodide 314 / emscripten 5 builds its main module with *native wasm*
# exception handling and wasm longjmp (see Pyodide's Makefile.envs). Side
# modules like libz3.so MUST match that ABI: building with the legacy
# `-fexceptions` (JS-based EH) makes libz3 import `invoke_*` trampolines that the
# Pyodide runtime no longer provides -> "cannot resolve symbol invoke_vi" at the
# first Z3 call. WASM_BIGINT is required because the Z3 C API passes 64-bit ints
# across the ctypes/JS boundary.
[tool.pyodide.build]
cflags = "-fwasm-exceptions -sSUPPORT_LONGJMP=wasm"
cxxflags = "-fwasm-exceptions -sSUPPORT_LONGJMP=wasm"
ldflags = "-fwasm-exceptions -sSUPPORT_LONGJMP=wasm -sWASM_BIGINT -sSIDE_MODULE=1"
# --- cibuildwheel: produce a PyPI-publishable pyemscripten wheel -------------
[tool.cibuildwheel]
# Pyodide 314 ships CPython 3.14; match the single ABI it targets.
build = "cp314-*"
[tool.cibuildwheel.pyodide]
# z3test.py is the upstream smoke test; run it inside the Pyodide test venv.
test-command = "python {project}/z3test.py z3"

View file

@ -42,9 +42,16 @@ if RELEASE_DIR is None:
BUILD_PLATFORM = "emscripten"
BUILD_ARCH = "wasm32"
BUILD_OS_VERSION = os.environ['_PYTHON_HOST_PLATFORM'].split('_')[1:-1]
build_env['CFLAGS'] = build_env.get('CFLAGS', '') + " -fexceptions"
build_env['CXXFLAGS'] = build_env.get('CXXFLAGS', '') + " -fexceptions"
build_env['LDFLAGS'] = build_env.get('LDFLAGS', '') + " -fexceptions"
# Match Pyodide's native-wasm exception/longjmp ABI (see Makefile.envs in
# Pyodide). The legacy JS-based "-fexceptions" makes libz3.so import
# invoke_* trampolines that the modern Pyodide runtime does not export,
# which surfaces as "cannot resolve symbol invoke_vi" on the first Z3
# call. These mirror [tool.pyodide.build] in pyproject.toml so direct
# `pyodide build` invocations stay consistent with cibuildwheel.
_wasm_eh = " -fwasm-exceptions -sSUPPORT_LONGJMP=wasm"
build_env['CFLAGS'] = build_env.get('CFLAGS', '') + _wasm_eh
build_env['CXXFLAGS'] = build_env.get('CXXFLAGS', '') + _wasm_eh
build_env['LDFLAGS'] = build_env.get('LDFLAGS', '') + _wasm_eh + " -sWASM_BIGINT -sSIDE_MODULE=1"
IS_SINGLE_THREADED = True
ENABLE_LTO = False
# build with pthread doesn't work. The WASM bindings are also single threaded.
@ -305,6 +312,21 @@ class bdist_wheel(_bdist_wheel):
def finalize_options(self):
if BUILD_PLATFORM == "emscripten":
# Under pyodide-build / `cibuildwheel --platform pyodide`, the
# authoritative wheel platform tag is handed to us verbatim via
# _PYTHON_HOST_PLATFORM. For PEP 783 (Pyodide >= 0.28 / "314") this
# is e.g. "pyemscripten_2026_0_wasm32" -- a tag PyPI accepts. The
# reconstruction below instead produced "emscripten_<ver>_wasm32",
# which is locked to a Pyodide release and rejected by PyPI, so we
# defer to pyodide-build's tag when it is available.
host_platform = os.environ.get('_PYTHON_HOST_PLATFORM')
if host_platform:
self.plat_name = host_platform
else:
os_version_tag = '_'.join(BUILD_OS_VERSION) if BUILD_OS_VERSION else 'xxxxxx'
self.plat_name = f"emscripten_{os_version_tag}_wasm32"
return super().finalize_options()
if BUILD_ARCH is not None and BUILD_PLATFORM is not None:
os_version_tag = '_'.join(BUILD_OS_VERSION) if BUILD_OS_VERSION is not None else 'xxxxxx'
os_version_tag = self.remove_build_machine_os_version(BUILD_PLATFORM, os_version_tag)

View file

@ -43,6 +43,7 @@ z3_add_component(rewriter
seq_rewriter.cpp
seq_regex_bisim.cpp
seq_skolem.cpp
term_enumeration.cpp
th_rewriter.cpp
value_sweep.cpp
var_subst.cpp

View file

@ -768,9 +768,10 @@ void bit_blaster_tpl<Cfg>::mk_smod(unsigned sz, expr * const * a_bits, expr * co
template<typename Cfg>
void bit_blaster_tpl<Cfg>::mk_eq(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref & out) {
expr_ref_vector out_bits(m());
out_bits.resize(sz);
for (unsigned i = 0; i < sz; ++i) {
mk_iff(a_bits[i], b_bits[i], out);
out_bits.push_back(out);
out_bits[i] = out;
}
mk_and(out_bits.size(), out_bits.data(), out);
}

View file

@ -86,9 +86,15 @@ namespace seq {
}
/*
Collect the leaves of a t-regex der (an ITE / antimirov union /
union-tree with regex leaves) into the output vector. Empty
(re.empty) leaves are dropped.
Collect the leaves of a t-regex der (an ITE-tree whose leaves are
regex expressions) into the output vector. Empty (re.empty) leaves
are dropped.
Each leaf is treated as a single bisimulation state regardless of
its top-level shape (including re.union and re.antimirov_union):
descending into a union at the leaf would split one state into
several, which is semantically unsound for the bisimulation /
union-find merging that follows.
Returns false if we encountered an unexpected node (e.g. a free
variable creeping in) in that case the caller should bail out.
@ -102,9 +108,7 @@ namespace seq {
expr* e = work.back();
work.pop_back();
expr* c = nullptr, * t = nullptr, * f = nullptr;
if (m.is_ite(e, c, t, f) ||
m_util.re.is_union(e, t, f) ||
m_util.re.is_antimirov_union(e, t, f)) {
if (m.is_ite(e, c, t, f)) {
if (seen.insert_if_not_there(t))
work.push_back(t);
if (seen.insert_if_not_there(f))

View file

@ -3314,11 +3314,20 @@ expr_ref seq_rewriter::mk_antimirov_deriv_restrict(expr* e, expr* d, expr* cond)
expr_ref seq_rewriter::mk_regex_union_normalize(expr* r1, expr* r2) {
expr_ref _r1(r1, m()), _r2(r2, m());
expr *a1, *b1, *a2, *b2;
SASSERT(m_util.is_re(r1));
SASSERT(m_util.is_re(r2));
expr_ref result(m());
std::function<bool(expr*, expr*&, expr*&)> test = [&](expr* t, expr*& a, expr*& b) { return re().is_union(t, a, b); };
std::function<expr* (expr*, expr*)> compose = [&](expr* r1, expr* r2) { return (is_subset(r1, r2) ? r2 : (is_subset(r2, r1) ? r1 : re().mk_union(r1, r2))); };
std::function<bool(expr *, expr *)> is_complement = [&](expr *a, expr *b) {
expr *s;
if (re().is_complement(a, s) && s == b)
return true;
if (re().is_complement(b, s) && s == a)
return true;
return false;
};
if (r1 == r2 || re().is_empty(r2) || re().is_full_seq(r1))
result = r1;
else if (re().is_empty(r1) || re().is_full_seq(r2))
@ -3327,8 +3336,28 @@ expr_ref seq_rewriter::mk_regex_union_normalize(expr* r1, expr* r2) {
result = r1;
else if (re().is_dot_plus(r2) && re().get_info(r1).min_length > 0)
result = r2;
else
result = merge_regex_sets(r1, r2, re().mk_full_seq(r1->get_sort()), test, compose);
// (R1 \ R2) U (R2 \ R1) = R1 xor R2
else if (false && re().is_intersection(r1, a1, a2) && re().is_intersection(r2, b1, b2) &&
is_complement(a1, b2) && is_complement(a2, b1)) {
result = re().mk_xor(a1, re().mk_complement(a2));
}
else if (false && re().is_intersection(r1, a1, a2) && re().is_intersection(r2, b1, b2) &&
is_complement(a1, b1) && is_complement(a2, b2)) {
result = re().mk_xor(a1, re().mk_complement(a2));
}
else {
// Range Range: [a,b] [c,d] = [min(a,c), max(b,d)] when overlapping or adjacent
unsigned lo1_v = 0, hi1_v = 0, lo2_v = 0, hi2_v = 0;
if (re().is_range(r1, lo1_v, hi1_v) && re().is_range(r2, lo2_v, hi2_v) &&
lo2_v <= hi1_v + 1 && lo1_v <= hi2_v + 1) {
unsigned new_lo = std::min(lo1_v, lo2_v);
unsigned new_hi = std::max(hi1_v, hi2_v);
result = re().mk_range(r1->get_sort(), new_lo, new_hi);
}
else
result = merge_regex_sets(r1, r2, re().mk_full_seq(r1->get_sort()), test, compose);
}
return result;
}
@ -3357,8 +3386,17 @@ expr_ref seq_rewriter::mk_regex_inter_normalize(expr* r1, expr* r2) {
result = r2;
else if (re().is_dot_plus(r2) && re().get_info(r1).min_length > 0)
result = r1;
else
result = merge_regex_sets(r1, r2, re().mk_empty(r1->get_sort()), test, compose);
else {
// Range ∩ Range: [a,b] ∩ [c,d] = [max(a,c), min(b,d)] or empty
unsigned lo1_v = 0, hi1_v = 0, lo2_v = 0, hi2_v = 0;
if (re().is_range(r1, lo1_v, hi1_v) && re().is_range(r2, lo2_v, hi2_v)) {
unsigned new_lo = std::max(lo1_v, lo2_v);
unsigned new_hi = std::min(hi1_v, hi2_v);
result = re().mk_range(r1->get_sort(), new_lo, new_hi);
}
else
result = merge_regex_sets(r1, r2, re().mk_empty(r1->get_sort()), test, compose);
}
return result;
}
@ -4787,6 +4825,42 @@ br_status seq_rewriter::mk_re_complement(expr* a, expr_ref& result) {
result = re().mk_plus(re().mk_full_char(a->get_sort()));
return BR_DONE;
}
// Range complement: comp([a,b]) → [0,a-1] [b+1,max] (or one half when a=0 or b=max)
unsigned lo_v = 0, hi_v = 0;
if (re().is_range(a, lo_v, hi_v)) {
unsigned max_c = u().max_char();
sort *srt = a->get_sort(), *seq_sort;
VERIFY(m_util.is_re(a, seq_sort));
bool has_left = (lo_v > 0);
bool has_right = (hi_v < max_c);
auto empty_re = [&]() { return re().mk_empty(srt); };
auto len0_re = [&]() { return re().mk_to_re(str().mk_empty(seq_sort)); };
auto full_re = [&]() { return re().mk_full_seq(srt); };
if (!has_left && !has_right) {
// [0, max_c]: complement is empty
result = empty_re();
return BR_DONE;
}
if (lo_v > hi_v) {
result = full_re();
return BR_DONE;
}
if (!has_left) {
// [0, b]: complement is [b+1, max]
result = re().mk_union(len0_re(), re().mk_concat(re().mk_range(srt, hi_v + 1, max_c), full_re()));
return BR_DONE;
}
if (!has_right) {
// [a, max]: complement is [0, a-1]
result = re().mk_union(len0_re(), re().mk_concat(re().mk_range(srt, 0u, lo_v - 1), full_re()));
return BR_DONE;
}
// General: [a, b] → [0, a-1] [b+1, max]
auto left = re().mk_range(srt, 0u, lo_v - 1);
auto right = re().mk_range(srt, hi_v + 1, max_c);
result = re().mk_union(len0_re(), re().mk_concat(re().mk_union(left, right), full_re()));
return BR_DONE;
}
return BR_FAILED;
}
@ -5084,6 +5158,11 @@ br_status seq_rewriter::mk_re_range(expr* lo, expr* hi, expr_ref& result) {
result = re().mk_empty(srt);
return BR_DONE;
}
// Singleton: re.range "a" "a" → str.to_re "a"
if (slo.length() == 1 && shi.length() == 1 && slo[0] == shi[0]) {
result = re().mk_to_re(lo);
return BR_DONE;
}
return BR_FAILED;
}

View file

@ -0,0 +1,674 @@
/**
* term_enumeration.cpp - Bottom-up term enumeration module for Z3
*
* Inspired by the Probe synthesizer (Barke et al., "Just-in-Time Learning
* for Bottom-Up Enumerative Synthesis"). Adapted to use Z3's internal APIs.
*
* Key ideas:
* - Terms are enumerated bottom-up by "cost" (calculated by tree size).
* - A grammar describes which function symbols (operators) and leaves
* (constants, variables) are available for enumeration.
*/
#include <sstream>
#include <functional>
#include <string>
#include "util/vector.h"
#include "util/scoped_ptr_vector.h"
#include "util/obj_hashtable.h"
#include "util/uint_set.h"
#include "ast/ast.h"
#include "ast/ast_ll_pp.h"
#include "ast/ast_pp.h"
#include "ast/rewriter/th_rewriter.h"
#include "ast/rewriter/term_enumeration.h"
namespace term_enum {
// ============================================================================
// grammar production rule
// ============================================================================
/**
* A production describes how to construct a term from child terms.
* - domain: the sort required for each child
* - range: the sort of the produced term
* - builder: given a vector of child exprs, produce the result expr
*/
struct production {
std::string name;
sort_ref range;
sort_ref_vector domain;
std::function<expr_ref(expr_ref_vector const&)> builder;
bool is_leaf() const { return domain.empty(); }
};
// ============================================================================
// grammar
// ============================================================================
/**
* A grammar groups productions into leaves (arity 0) and operators (arity > 0).
*/
class grammar {
public:
grammar(ast_manager& m) : m(m), m_pinned(m) {}
void add_production(production* p) {
if (p->is_leaf())
m_leaves.push_back(p);
else
m_operators.push_back(p);
}
scoped_ptr_vector<production> const& leaves() const { return m_leaves; }
scoped_ptr_vector<production> const& operators() const { return m_operators; }
ast_manager& mgr() const { return m; }
void add_func_decl(func_decl *f) {
if (m_seen.contains(f))
return;
m_pinned.push_back(f);
m_seen.insert(f);
sort_ref range(f->get_range(), m);
sort_ref_vector dom(m);
for (unsigned i = 0; i < f->get_arity(); ++i)
dom.push_back(sort_ref(f->get_domain(i), m));
add_production(alloc(production, {f->get_name().str(), range, dom, [this, f](expr_ref_vector const &args) {
return expr_ref(m.mk_app(f, args), m);
}}));
}
void add_expr(expr *e) {
if (m_seen.contains(e))
return;
m_pinned.push_back(e);
m_seen.insert(e);
sort_ref range(e->get_sort(), m);
sort_ref_vector dom(m);
std::stringstream ss;
ss << mk_bounded_pp(e, m);
std::string name = ss.str();
add_production(alloc(production, {name, range, dom, [this, e](expr_ref_vector const&) { return expr_ref(e, m); }}));
}
std::ostream& display(std::ostream& out) const {
out << "Leaves:\n";
for (auto const *p : m_leaves) {
out << " " << p->name << " : " << mk_pp(p->range, m) << "\n";
}
out << "Operators:\n";
for (auto const *p : m_operators) {
out << " " << p->name << " : (";
for (unsigned i = 0; i < p->domain.size(); ++i) {
if (i > 0)
out << ", ";
out << mk_pp(p->domain[i], m);
}
out << ") -> " << mk_pp(p->range, m) << "\n";
}
return out;
}
private:
ast_manager& m;
ast_ref_vector m_pinned;
scoped_ptr_vector<production> m_leaves;
scoped_ptr_vector<production> m_operators;
obj_hashtable<ast> m_seen;
};
// ============================================================================
// Term Bank - stores enumerated terms by cost and sort
// ============================================================================
using cost_terms = vector<std::pair<expr*, unsigned>>;
class term_bank {
using sort_term_map = obj_map<sort, ptr_vector<expr>>;
public:
term_bank(ast_manager& m) : m(m), m_pinned(m) {}
~term_bank() {
for (auto s : m_terms)
dealloc(s);
}
void reset() {
m_pinned.reset();
m_terms.clear();
}
void add(expr* term, unsigned cost) {
sort* s = term->get_sort();
m_pinned.push_back(term);
if (cost >= m_terms.size())
m_terms.resize(cost + 1);
if (!m_terms[cost])
m_terms[cost] = alloc(sort_term_map);
m_terms[cost]->insert_if_not_there(s, ptr_vector<expr>()).push_back(term);
}
/** Get all terms of a given sort up to (and including) max_cost */
cost_terms get_by_sort(sort* s, unsigned max_cost) const {
cost_terms result;
for (unsigned c = 0; c <= max_cost; ++c) {
if (c >= m_terms.size())
break;
if (!m_terms[c]->contains(s))
continue;
for (auto t : m_terms[c]->find(s))
result.push_back({t, c});
}
return result;
}
// Return true if there is at least one term at/above `cost` whose sort is
// not in `sorts` (i.e., enumeration can still produce a new requested sort).
bool is_productive(unsigned cost, uint_set const& sorts) {
for (unsigned i = cost; i < m_terms.size(); ++i) {
if (!m_terms[i])
continue;
for (auto const& entry : *m_terms[i]) {
sort* term_sort = entry.m_key;
if (!sorts.contains(term_sort->get_small_id()))
return true;
}
}
return false;
}
ptr_vector<expr> null_ptr_vector;
ptr_vector<expr> const &get_by_cost_and_sort(unsigned cost, sort *s) const {
if (cost >= m_terms.size() || !m_terms[cost] || !m_terms[cost]->contains(s))
return null_ptr_vector;
return m_terms[cost]->find(s);
}
std::ostream& display(std::ostream& out) const {
for (unsigned cost = 0; cost < m_terms.size(); ++cost) {
if (!m_terms[cost])
continue;
out << "cost " << cost << ":\n";
for (auto& [s, terms] : *m_terms[cost]) {
out << " sort " << mk_pp(s, m) << ":\n";
for (expr* e : terms) {
out << " #" << e->get_id() << " ";
if (cost == 0) {
out << mk_bounded_pp(e, m);
}
else if (is_app(e)) {
app* a = to_app(e);
out << a->get_decl()->get_name() << "(";
bool first = true;
for (expr* arg : *a) {
if (!first) out << ", ";
first = false;
out << "#" << arg->get_id();
}
out << ")";
}
out << "\n";
}
}
}
return out;
}
private:
ast_manager& m;
expr_ref_vector m_pinned;
// cost -> sort -> terms
ptr_vector<sort_term_map> m_terms;
};
// ============================================================================
// Children Iterator - generates all combinations of child terms
// ============================================================================
/**
* Iterates over all tuples (c1, c2, ..., cn) where each ci has the required
* sort, drawn from the term bank, with at least one child at the current
* cost - 1 (to avoid regenerating previously seen terms).
*/
class children_iterator {
public:
children_iterator(ast_manager& m, production const& prod, term_bank const& bank, unsigned current_cost)
: m(m), m_prod(prod), m_current_cost(current_cost), m_done(false)
{
m_arity = prod.domain.size();
if (m_arity == 0) {
m_done = true;
return;
}
for (unsigned i = 0; i < m_arity; ++i) {
m_candidates.push_back(bank.get_by_sort(prod.domain[i], current_cost - 1));
if (m_candidates.back().empty()) {
m_done = true;
return;
}
}
m_indices.resize(m_arity, 0);
}
bool has_next(unsigned cost) {
while (!m_done) {
if (has_child_at_cost(cost))
return true;
advance();
}
return false;
}
expr_ref_vector next(unsigned& cost) {
expr_ref_vector result(m);
cost = 1;
for (unsigned i = 0; i < m_arity; ++i) {
auto [e, c] = m_candidates[i].get(m_indices[i]);
cost += c;
result.push_back(e);
}
advance();
return result;
}
private:
ast_manager& m;
production const& m_prod;
unsigned m_current_cost;
unsigned m_arity;
bool m_done;
vector<cost_terms> m_candidates;
svector<unsigned> m_indices;
bool has_child_at_cost(unsigned cost) const {
for (unsigned i = 0; i < m_arity; ++i) {
auto [e, c] = m_candidates[i].get(m_indices[i]);
if (c + 1 == cost)
return true;
}
return false;
}
void advance() {
for (auto i = m_arity; i-- > 0;) {
m_indices[i]++;
if (m_indices[i] < m_candidates[i].size()) return;
m_indices[i] = 0;
}
m_done = true;
}
};
// ============================================================================
// bottom_up_enumerator - the main bottom-up term enumeration engine
// ============================================================================
class bottom_up_enumerator {
public:
bottom_up_enumerator(grammar& grammar)
: m_grammar(grammar), m(grammar.mgr()),
m_bank(grammar.mgr()), m_pending(grammar.mgr()), m_rewriter(grammar.mgr())
{}
void set_target_sort(sort *s) {
m_target_sort = s;
}
bool has_next() {
if (m_pending) return true;
m_pending = find_next();
return m_pending != nullptr;
}
expr_ref next() {
if (!m_pending)
m_pending = find_next();
expr_ref result(m_pending, m);
m_pending = nullptr;
return result;
}
term_bank const& bank() const { return m_bank; }
std::ostream& display(std::ostream& out) const {
m_grammar.display(out);
return m_bank.display(out);
}
void reset() {
m_cost = 0;
m_leaf_idx = 0;
m_op_idx = 0;
m_state = State::Leaves;
m_bank.reset();
m_pending = nullptr;
m_rewriter.reset();
m_seen_terms.reset();
m_children_iter.reset();
}
expr* add_term(expr_ref const& term, unsigned cost) {
expr_ref simplified(m);
m_rewriter(term, simplified);
if (m_seen_terms.contains(simplified))
return nullptr;
m_seen_terms.insert(simplified);
m_bank.add(simplified, cost);
return simplified;
}
private:
enum class State { Leaves, Operators, Done };
grammar& m_grammar;
ast_manager& m;
term_bank m_bank;
unsigned m_cost = 0;
unsigned m_leaf_idx = 0;
unsigned m_op_idx = 0;
unsigned m_bank_idx = 0;
unsigned m_bank_size = 0;
bool m_made_progress = false;
uint_set m_sorts_produced;
State m_state = State::Leaves;
expr_ref m_pending;
th_rewriter m_rewriter;
obj_hashtable<expr> m_seen_terms;
std::unique_ptr<children_iterator> m_children_iter;
sort *m_target_sort = nullptr;
bool sort_matches(expr* e) const {
return !m_target_sort || e->get_sort() == m_target_sort;
}
expr* find_next() {
while (true) {
switch (m_state) {
case State::Leaves:
while (m_leaf_idx < m_grammar.leaves().size()) {
production const &prod = *m_grammar.leaves()[m_leaf_idx];
m_leaf_idx++;
expr_ref_vector empty_args(m);
expr_ref term = prod.builder(empty_args);
expr* r = add_term(term, 0);
if (r && sort_matches(r))
return r;
}
m_state = State::Operators;
m_cost = 1;
m_op_idx = 0;
m_bank_idx = 0;
m_bank_size = get_bank_size();
m_made_progress = false;
m_sorts_produced.reset();
m_children_iter.reset();
break;
case State::Operators: {
expr* result = enumerate_operators();
if (result)
return result;
m_cost++;
m_op_idx = 0;
m_bank_idx = 0;
m_bank_size = get_bank_size();
m_children_iter.reset();
if (!m_made_progress && !m_bank.is_productive(m_cost, m_sorts_produced)) {
m_state = State::Done;
return nullptr;
}
if (m_sorts_produced.contains(m_target_sort->get_small_id()))
m_sorts_produced.reset();
m_made_progress = false;
break;
}
case State::Done:
return nullptr;
}
}
}
unsigned get_bank_size() const {
auto const &terms = m_bank.get_by_cost_and_sort(m_cost, m_target_sort);
return terms.size();
}
expr *enumerate_operators() {
auto const &ops = m_grammar.operators();
while (true) {
// first find terms at m_cost that were already created
if (m_bank_idx < m_bank_size) {
auto const &terms = m_bank.get_by_cost_and_sort(m_cost, m_target_sort);
auto t = terms.get(m_bank_idx);
m_bank_idx++;
SASSERT(sort_matches(t));
return t;
}
// then create new terms using children at cost below current m_cost.
if (m_children_iter && m_children_iter->has_next(m_cost)) {
unsigned new_cost = 0;
expr_ref_vector children = m_children_iter->next(new_cost);
production const &prod = *ops[m_op_idx - 1];
expr_ref term = prod.builder(children);
// IF_VERBOSE(0, verbose_stream() << term << "\n");
SASSERT(new_cost >= m_cost);
expr* r = add_term(term, new_cost);
if (!r)
continue;
unsigned sort_id = r->get_sort()->get_small_id();
if (!m_sorts_produced.contains(sort_id))
m_made_progress = true;
m_sorts_produced.insert(sort_id);
if (sort_matches(r) && new_cost == m_cost) {
return r;
}
continue;
}
if (m_op_idx >= ops.size())
return nullptr;
production const &prod = *ops[m_op_idx];
m_op_idx++;
m_children_iter = std::make_unique<children_iterator>(m, prod, m_bank, m_cost);
}
}
};
} // namespace term_enum
// ============================================================================
// term_enumeration public interface implementation
// ============================================================================
struct term_enumeration::imp {
ast_manager& m;
term_enum::grammar m_grammar;
term_enum::bottom_up_enumerator m_bottom_up_enumerator;
std::function<unsigned(expr*)> m_cost;
imp(ast_manager& m) :
m(m), m_grammar(m), m_bottom_up_enumerator(m_grammar) {}
void add_production(func_decl* f) {
m_grammar.add_func_decl(f);
}
void add_production(expr* e) {
m_grammar.add_expr(e);
}
void set_cost(std::function<unsigned(expr*)> const& cost) {
// TODO
}
std::ostream& display(std::ostream& out) const {
return m_bottom_up_enumerator.display(out);
}
};
// -- iterator implementation --
struct term_enumeration::iterator::iter_imp {
imp& m_imp;
ast_manager & m;
sort* m_sort;
unsigned m_cost = 0;
unsigned m_idx = 0;
vector<expr_ref_vector> m_levels;
expr_ref m_current;
bool m_end;
vector<expr_ref_vector> m_vars;
vector<ptr_vector<sort>> m_decls;
vector<vector<symbol>> m_names;
iter_imp(imp& i, sort* s) : m_imp(i), m(i.m), m_sort(s), m_current(i.m), m_end(false) {
m_imp.m_bottom_up_enumerator.reset();
init_sort();
advance();
}
// Sentinel constructor
iter_imp(imp& i) :
m_imp(i), m(i.m), m_sort(nullptr), m_current(i.m), m_end(true) {
UNREACHABLE();
}
void init_sort() {
array_util autil(m);
sort *range = m_sort;
while (autil.is_array(range)) {
m_vars.push_back(expr_ref_vector(m));
m_decls.push_back(ptr_vector<sort>());
m_names.push_back(vector<symbol>());
for (unsigned i = 0; i < get_array_arity(range); ++i) {
m_decls.back().push_back(get_array_domain(range, i));
m_vars.back().push_back(nullptr);
m_names.back().push_back(symbol());
}
expr_ref_vector args(m);
args.push_back(m.mk_const("a", range));
for (unsigned i = 0; i < m_decls.back().size(); ++i) {
args.push_back(m.mk_var(i, m_decls.back().get(i)));
}
app_ref sel(autil.mk_select(args), m);
m_imp.m_grammar.add_func_decl(sel->get_decl());
range = get_array_range(range);
}
unsigned n = 0;
for (unsigned i = m_decls.size(); i-- > 0;) {
for (unsigned j = m_decls[i].size(); j-- > 0;) {
m_vars[i][j] = m.mk_var(n, m_decls[i][j]);
m_names[i][j] = symbol(n);
m_imp.add_production(m_vars[i].get(j));
n++;
}
}
m_sort = range;
m_imp.m_bottom_up_enumerator.set_target_sort(range);
}
void mk_lambda() {
if (!m_current)
return;
for (unsigned i = m_decls.size(); i-- > 0;)
m_current = m.mk_lambda(m_decls[i].size(), m_decls[i].data(), m_names[i].data(), m_current);
}
void advance() {
if (m_end)
return;
m_current = m_imp.m_bottom_up_enumerator.next();
SASSERT(!m_current || m_current->get_sort() == m_sort);
mk_lambda();
if (!m_current)
m_end = true;
}
};
term_enumeration::iterator::iterator(imp& i, sort* s) {
m_imp = alloc(iter_imp, i, s);
}
term_enumeration::iterator::iterator(std::nullptr_t) {
m_imp = nullptr;
}
term_enumeration::iterator::~iterator() {
dealloc(m_imp);
}
expr* term_enumeration::iterator::operator*() {
return m_imp ? m_imp->m_current.get() : nullptr;
}
term_enumeration::iterator& term_enumeration::iterator::operator++() {
if (m_imp) m_imp->advance();
return *this;
}
term_enumeration::iterator term_enumeration::iterator::operator++(int) {
iterator tmp(*this);
++(*this);
return tmp;
}
bool term_enumeration::iterator::operator==(iterator const& other) const {
if (!m_imp && !other.m_imp) return true;
if (!m_imp) return other.m_imp->m_end;
if (!other.m_imp) return m_imp->m_end;
return m_imp->m_end == other.m_imp->m_end &&
m_imp->m_current == other.m_imp->m_current;
}
// -- terms implementation --
term_enumeration::terms::terms(imp* i, sort* s) : m_imp(i), m_sort(s) {}
term_enumeration::iterator term_enumeration::terms::begin() {
return iterator(*m_imp, m_sort);
}
term_enumeration::iterator term_enumeration::terms::end() {
return iterator(nullptr);
}
// -- term_enumeration implementation --
term_enumeration::term_enumeration(ast_manager& m) {
m_imp = alloc(imp, m);
}
term_enumeration::~term_enumeration() {
dealloc(m_imp);
}
void term_enumeration::add_production(func_decl* f) {
m_imp->add_production(f);
}
void term_enumeration::add_production(expr* e) {
m_imp->add_production(e);
}
void term_enumeration::set_cost(std::function<unsigned(expr*)> const& cost) {
m_imp->set_cost(cost);
}
term_enumeration::terms term_enumeration::enum_terms(sort* s) {
return terms(m_imp, s);
}
std::ostream& term_enumeration::display(std::ostream& out) const {
return m_imp->display(out);
}

View file

@ -0,0 +1,50 @@
#pragma once
#include "ast/ast.h"
#include <functional>
class term_enumeration {
struct imp;
imp* m_imp;
public:
term_enumeration(ast_manager& m);
~term_enumeration();
void add_production(func_decl* f);
void add_production(expr* e);
// void add_production(sort *s, std::function<expr *()> g);
// cost function associated with expressions.
// terms are enumerated with increasing cost.
void set_cost(std::function<unsigned(expr*)> const& cost);
class iterator {
struct iter_imp;
iter_imp* m_imp;
public:
iterator(imp& i, sort* s);
iterator(std::nullptr_t);
~iterator();
expr* operator*();
iterator operator++(int);
iterator& operator++();
bool operator!=(iterator const& other) const {
return !(*this == other);
}
bool operator==(iterator const &other) const;
};
class terms {
imp* m_imp;
sort* m_sort;
public:
terms(imp* i, sort* s);
iterator begin();
iterator end();
};
terms enum_terms(sort* s);
std::ostream& display(std::ostream& out) const;
};

View file

@ -1208,6 +1208,15 @@ app* seq_util::rex::mk_of_pred(expr* p) {
return m.mk_app(m_fid, OP_RE_OF_PRED, 0, nullptr, 1, &p);
}
app* seq_util::rex::mk_range(sort* re_sort, unsigned lo, unsigned hi) {
if (lo > hi)
return mk_empty(re_sort);
app* lo_str = u.str.mk_string(zstring(lo));
if (lo == hi)
return mk_to_re(lo_str);
return mk_range(lo_str, u.str.mk_string(zstring(hi)));
}
bool seq_util::rex::is_loop(expr const* n, expr*& body, unsigned& lo, unsigned& hi) const {
if (is_loop(n)) {
app const* a = to_app(n);
@ -1671,11 +1680,19 @@ seq_util::rex::info seq_util::rex::mk_info_rec(app* e) const {
case OP_RE_OPTION:
i1 = get_info_rec(e->get_arg(0));
return i1.opt();
case OP_RE_RANGE:
case OP_RE_RANGE: {
// A concrete range [lo, hi] with lo <= hi is non-empty and classical.
zstring slo, shi;
if (u.str.is_string(e->get_arg(0), slo) && slo.length() == 1 &&
u.str.is_string(e->get_arg(1), shi) && shi.length() == 1 &&
slo[0] <= shi[0])
return info(true, l_false, 1, true);
// Symbolic or unknown: not classical
return info(true, l_false, 1, false);
}
case OP_RE_FULL_CHAR_SET:
case OP_RE_OF_PRED:
//TBD: check if the character predicate contains uninterpreted symbols or is nonground or is unsat
//TBD: check if the range is unsat
return info(true, l_false, 1, false);
case OP_RE_CONCAT:
i1 = get_info_rec(e->get_arg(0));

View file

@ -521,6 +521,8 @@ public:
app* mk_to_re(expr* s) { return m.mk_app(m_fid, OP_SEQ_TO_RE, 1, &s); }
app* mk_in_re(expr* s, expr* r) { return m.mk_app(m_fid, OP_SEQ_IN_RE, s, r); }
app* mk_range(expr* s1, expr* s2) { return m.mk_app(m_fid, OP_RE_RANGE, s1, s2); }
// Smart constructor: returns re.empty / str.to_re / re.range based on lo vs hi.
app* mk_range(sort* re_sort, unsigned lo, unsigned hi);
app* mk_concat(expr* r1, expr* r2) { return m.mk_app(m_fid, OP_RE_CONCAT, r1, r2); }
app* mk_union(expr* r1, expr* r2) { return m.mk_app(m_fid, OP_RE_UNION, r1, r2); }
app* mk_inter(expr* r1, expr* r2) { return m.mk_app(m_fid, OP_RE_INTERSECT, r1, r2); }

View file

@ -45,7 +45,7 @@ Author:
class dependent_expr_state {
unsigned m_qhead = 0;
bool m_suffix_frozen = false;
unsigned m_num_recfun = 0, m_num_lambdas = 0;
unsigned m_num_recfun = 0;
lbool m_has_quantifiers = l_undef;
ast_mark m_frozen;
func_decl_ref_vector m_frozen_trail;

View file

@ -17,45 +17,51 @@ Notes:
--*/
#pragma once
#define ATOMIC_CMD(CLS_NAME, NAME, DESCR, ACTION) \
#define ATOMIC_CMD(CLS_NAME, NAME, DESCR, ACTION) \
class CLS_NAME : public cmd { \
public: \
CLS_NAME():cmd(NAME) {} \
char const * get_usage() const override { return 0; } \
char const * get_descr(cmd_context & ctx) const override { \
return DESCR; \
} \
unsigned get_arity() const override { return 0; } \
void execute(cmd_context & ctx) override { ACTION } \
}
#define UNARY_CMD(CLS_NAME, NAME, USAGE, DESCR, ARG_KIND, ARG_TYPE, ACTION) \
class CLS_NAME : public cmd { \
public: \
CLS_NAME():cmd(NAME) {} \
virtual char const * get_usage() const { return 0; } \
virtual char const * get_descr(cmd_context & ctx) const { return DESCR; } \
virtual unsigned get_arity() const { return 0; } \
virtual void execute(cmd_context & ctx) { ACTION } \
};
#define UNARY_CMD(CLS_NAME, NAME, USAGE, DESCR, ARG_KIND, ARG_TYPE, ACTION) \
class CLS_NAME : public cmd { \
public: \
CLS_NAME():cmd(NAME) {} \
virtual char const * get_usage() const { return USAGE; } \
virtual char const * get_descr(cmd_context & ctx) const { return DESCR; } \
virtual unsigned get_arity() const { return 1; } \
virtual cmd_arg_kind next_arg_kind(cmd_context & ctx) const { return ARG_KIND; } \
virtual void set_next_arg(cmd_context & ctx, ARG_TYPE arg) { ACTION } \
char const * get_usage() const override { return USAGE; } \
char const * get_descr(cmd_context & ctx) const override { \
return DESCR; \
} \
unsigned get_arity() const override { return 1; } \
cmd_arg_kind next_arg_kind(cmd_context & ctx) const override { \
return ARG_KIND; \
} \
void set_next_arg(cmd_context & ctx, ARG_TYPE arg) override { ACTION } \
}
// Macro for creating commands where the first argument is a symbol
// The second argument cannot be a symbol
#define BINARY_SYM_CMD(CLS_NAME, NAME, USAGE, DESCR, ARG_KIND, ARG_TYPE, ACTION) \
class CLS_NAME : public cmd { \
symbol m_sym; \
symbol m_sym; \
public: \
CLS_NAME():cmd(NAME) {} \
virtual char const * get_usage() const { return USAGE; } \
virtual char const * get_descr(cmd_context & ctx) const { return DESCR; } \
virtual unsigned get_arity() const { return 2; } \
virtual void prepare(cmd_context & ctx) { m_sym = symbol::null; } \
virtual cmd_arg_kind next_arg_kind(cmd_context & ctx) const { \
return m_sym == symbol::null ? CPK_SYMBOL : ARG_KIND; \
char const * get_usage() const override { return USAGE; } \
char const * get_descr(cmd_context & ctx) const override { return DESCR; } \
unsigned get_arity() const override { return 2; } \
void prepare(cmd_context & ctx) override { m_sym = symbol::null; } \
cmd_arg_kind next_arg_kind(cmd_context & ctx) const override { \
return m_sym == symbol::null ? CPK_SYMBOL : ARG_KIND; \
} \
virtual void set_next_arg(cmd_context & ctx, symbol const & s) { m_sym = s; } \
virtual void set_next_arg(cmd_context & ctx, ARG_TYPE arg) { ACTION } \
};
void set_next_arg(cmd_context & ctx, symbol const & s) override { m_sym = s; } \
void set_next_arg(cmd_context & ctx, ARG_TYPE arg) override { ACTION } \
}
class ast;
class expr;

View file

@ -580,7 +580,7 @@ namespace lp {
const lar_term* m_t;
undo_add_term(imp& s, const lar_term* t) : m_s(s), m_t(t) {}
void undo() {
void undo() override {
m_s.undo_add_term_method(m_t);
}
};

View file

@ -16,6 +16,9 @@ Author:
Revision History:
--*/
#include <algorithm>
#include <unordered_map>
#include "math/lp/int_solver.h"
#include "math/lp/lar_solver.h"
#include "math/lp/int_cube.h"
@ -81,6 +84,252 @@ namespace lp {
SASSERT(lp_status::OPTIMAL == lra.get_status() || lp_status::FEASIBLE == lra.get_status());
}
// The largest cube test of Bromberger and Weidenbach:
// maximize x_e subject to Ax + a'(x_e/2) <= b, x_e >= 0, where a'_i = ||a_i||_1,
// with the 1-norm taken over the integer variables of the row.
// The solution is the center z of a largest cube contained in the polyhedron.
// If the maximal edge length is at least 1, then the rounding of z is
// an integer solution; otherwise the rounding is checked, and possibly repaired,
// against the original constraints.
lia_move int_cube::find_largest_cube() {
lia.settings().stats().m_lcube_calls++;
TRACE(cube,
for (unsigned j = 0; j < lra.number_of_vars(); ++j)
lia.display_column(tout, j);
tout << lra.constraints();
);
lra.push();
// The edge rows are ephemeral: suppress the add-term callback,
// dioph_eq's reaction to it is not undone by pop().
auto add_term_cb = lra.m_add_term_callback;
lra.m_add_term_callback = nullptr;
unsigned x_e = lra.add_var(UINT_MAX, false); // the edge length of the cube
lra.add_var_bound(x_e, lconstraint_kind::GE, mpq(0));
bool ok = add_cube_edge_rows(x_e);
lra.m_add_term_callback = add_term_cb;
if (!ok) {
lra.pop();
lra.set_status(lp_status::OPTIMAL);
return lia_move::undef;
}
lp_status st = lra.find_feasible_solution();
if (st != lp_status::FEASIBLE && st != lp_status::OPTIMAL) {
TRACE(cube, tout << "cannot find a feasible solution";);
lra.pop();
lra.move_non_basic_columns_to_bounds();
// it can happen that we found an integer solution here
return !lra.r_basis_has_inf_int()? lia_move::sat: lia_move::undef;
}
impq e; // the maximal edge length
st = lra.maximize_term(x_e, e, /*fix_int_cols*/ false);
if (lia.settings().get_cancel_flag()) {
lra.pop();
return lia_move::undef;
}
if (st == lp_status::UNBOUNDED) {
// infinite lattice width: the polyhedron contains cubes of arbitrary edge length
lra.add_var_bound(x_e, lconstraint_kind::GE, mpq(1));
st = lra.find_feasible_solution();
if (st != lp_status::FEASIBLE && st != lp_status::OPTIMAL) {
lra.pop();
return lia_move::undef;
}
lra.pop();
return sat_after_rounding();
}
TRACE(cube, tout << "max edge length = " << e << "\n";);
if (e >= impq(mpq(1))) {
lra.pop();
return sat_after_rounding();
}
// the largest cube is smaller than the unit cube:
// the rounded center is only a candidate
lra.pop();
return round_and_repair();
}
bool int_cube::add_cube_edge_rows(unsigned x_e) {
// snapshot the term columns: add_edge_rows_for_term appends to lra.terms()
svector<unsigned> term_columns;
for (const lar_term* t : lra.terms())
term_columns.push_back(t->j());
for (unsigned j : term_columns)
if (!add_edge_rows_for_term(j, x_e)) {
TRACE(cube, tout << "cannot add the edge rows";);
return false;
}
return true;
}
// i is the column index having the term
bool int_cube::add_edge_rows_for_term(unsigned i, unsigned x_e) {
if (!lra.column_associated_with_row(i))
return true;
const lar_term& t = lra.get_term(i);
impq delta = get_cube_delta_for_term(t);
TRACE(cube, lra.print_term_as_indices(t, tout); tout << ", delta = " << delta << "\n";);
if (is_zero(delta))
return true;
if (!is_zero(delta.y))
// the infinitesimal delta does not scale with x_e: tighten statically,
// it is sound for any edge length
return lra.tighten_term_bounds_by_delta(i, delta);
if (lra.column_has_upper_bound(i)) {
impq u = lra.get_upper_bound(i); // copy: add_term invalidates bound references
vector<std::pair<mpq, unsigned>> coeffs;
coeffs.push_back(std::make_pair(mpq(1), i));
coeffs.push_back(std::make_pair(delta.x, x_e));
unsigned s = lra.add_term(coeffs, UINT_MAX);
lra.add_var_bound(s, is_zero(u.y) ? lconstraint_kind::LE : lconstraint_kind::LT, u.x);
}
if (lra.column_has_lower_bound(i)) {
impq l = lra.get_lower_bound(i); // copy: add_term invalidates bound references
vector<std::pair<mpq, unsigned>> coeffs;
coeffs.push_back(std::make_pair(mpq(1), i));
coeffs.push_back(std::make_pair(-delta.x, x_e));
unsigned s = lra.add_term(coeffs, UINT_MAX);
lra.add_var_bound(s, is_zero(l.y) ? lconstraint_kind::GE : lconstraint_kind::GT, l.x);
}
return true;
}
lia_move int_cube::sat_after_rounding() {
lra.round_to_integer_solution();
lra.set_status(lp_status::FEASIBLE);
SASSERT(lia.settings().get_cancel_flag() || lia.is_feasible());
TRACE(cube, tout << "largest cube success";);
lia.settings().stats().m_lcube_success++;
return lia_move::sat;
}
lia_move int_cube::round_and_repair() {
lra.backup_x(); // remember the cube center
vector<flip_candidate> flips;
for (unsigned j = 0; j < lra.column_count(); ++j) {
if (!lra.column_is_int(j) || lra.column_has_term(j))
continue;
const impq& v = lra.get_column_value(j);
if (v.is_int())
continue;
flip_candidate f;
f.m_j = j;
f.m_lo = floor(v);
flips.push_back(f);
}
lra.round_to_integer_solution();
for (auto& f : flips)
f.m_at_hi = lra.get_column_value(f.m_j).x > f.m_lo;
if (repair_rounded_candidate(flips)) {
lra.set_status(lp_status::FEASIBLE);
SASSERT(lia.settings().get_cancel_flag() || lia.is_feasible());
TRACE(cube, tout << "largest cube success";);
lia.settings().stats().m_lcube_success++;
return lia_move::sat;
}
// return to the cube center: an interior point of the polyhedron
lra.restore_x();
lra.set_status(lp_status::FEASIBLE);
return lia_move::undef;
}
// Checks the rounded center against the original constraints. On failure
// searches the vertices of the lattice cell around the center greedily:
// flip a coordinate between floor and ceiling to maximally decrease the
// total bound violation, within a budget.
bool int_cube::repair_rounded_candidate(vector<flip_candidate>& flips) {
vector<bounded_row> rows;
for (const lar_term* t : lra.terms()) {
unsigned j = t->j();
if (!lra.column_associated_with_row(j))
continue;
if (!lra.column_has_upper_bound(j) && !lra.column_has_lower_bound(j))
continue;
bounded_row r;
r.m_j = j;
r.m_val = t->apply(lra.r_x());
rows.push_back(r);
}
auto row_violation = [&](unsigned ri, const impq& v) {
impq w;
unsigned j = rows[ri].m_j;
if (lra.column_has_upper_bound(j) && v > lra.get_upper_bound(j))
w += v - lra.get_upper_bound(j);
if (lra.column_has_lower_bound(j) && v < lra.get_lower_bound(j))
w += lra.get_lower_bound(j) - v;
return w;
};
impq violation;
for (unsigned ri = 0; ri < rows.size(); ++ri)
violation += row_violation(ri, rows[ri].m_val);
if (is_zero(violation))
return true; // the rounded center fits as it is
if (flips.empty())
return false;
std::unordered_map<unsigned, unsigned> flip_of_var;
for (unsigned fi = 0; fi < flips.size(); ++fi)
flip_of_var[flips[fi].m_j] = fi;
// occurrences of the flip candidates in the bounded rows
vector<vector<std::pair<unsigned, mpq>>> occs;
occs.resize(flips.size());
for (unsigned ri = 0; ri < rows.size(); ++ri) {
const lar_term& t = lra.get_term(rows[ri].m_j);
for (lar_term::ival p : t) {
auto it = flip_of_var.find(p.j());
if (it != flip_of_var.end())
occs[it->second].push_back(std::make_pair(ri, p.coeff()));
}
}
unsigned budget = std::min(2 * flips.size(), lia.settings().lcube_flips());
bool flipped = false;
while (!is_zero(violation) && budget-- > 0) {
unsigned best_fi = UINT_MAX;
impq best_gain;
for (unsigned fi = 0; fi < flips.size(); ++fi) {
if (occs[fi].empty())
continue;
mpq step = flips[fi].m_at_hi ? mpq(-1) : mpq(1);
impq gain;
for (const auto& o : occs[fi]) {
const impq& v = rows[o.first].m_val;
gain += row_violation(o.first, v + impq(step * o.second)) - row_violation(o.first, v);
}
if (gain < best_gain) {
best_gain = gain;
best_fi = fi;
}
}
if (best_fi == UINT_MAX)
return false; // no flip decreases the violation
mpq step = flips[best_fi].m_at_hi ? mpq(-1) : mpq(1);
for (const auto& o : occs[best_fi])
rows[o.first].m_val += impq(step * o.second);
flips[best_fi].m_at_hi = !flips[best_fi].m_at_hi;
violation += best_gain;
flipped = true;
TRACE(cube, tout << "flipped column " << flips[best_fi].m_j << ", violation = " << violation << "\n";);
}
if (!is_zero(violation))
return false;
// apply the repaired candidate
for (const auto& f : flips)
lra.set_column_value(f.m_j, impq(f.m_at_hi ? f.m_lo + 1 : f.m_lo));
for (const lar_term* t : lra.terms()) {
unsigned j = t->j();
if (!lra.column_associated_with_row(j))
continue;
lra.set_column_value(j, t->apply(lra.r_x()));
}
if (flipped)
lia.settings().stats().m_lcube_flip_success++;
return true;
}
impq int_cube::get_cube_delta_for_term(const lar_term& t) const {
if (t.size() == 2) {
bool seen_minus = false;

View file

@ -10,9 +10,15 @@ Abstract:
Cube finder
This routine attempts to find a feasible integer solution
by tightnening bounds and running an LRA solver on the
by tightnening bounds and running an LRA solver on the
tighter system.
find_largest_cube() implements the largest cube test of
Bromberger and Weidenbach (Fast Cube Tests for LIA Constraint
Solving, IJCAR 2016): a fresh variable x_e for the cube edge
length is introduced and maximized; the center of the largest
cube is rounded to a candidate integer solution.
Author:
Nikolaj Bjorner (nbjorner)
Lev Nachmanson (levnach)
@ -21,7 +27,10 @@ Revision History:
--*/
#pragma once
#include "util/vector.h"
#include "math/lp/lia_move.h"
#include "math/lp/numeric_pair.h"
#include "math/lp/lar_term.h"
namespace lp {
class int_solver;
@ -29,12 +38,30 @@ namespace lp {
class int_cube {
class int_solver& lia;
class lar_solver& lra;
// a fractional integer coordinate of the cube center:
// the candidate value is m_lo or m_lo + 1
struct flip_candidate {
unsigned m_j = 0;
mpq m_lo;
bool m_at_hi = false;
};
// a term column with at least one bound, tracked during the repair
struct bounded_row {
unsigned m_j = 0;
impq m_val;
};
bool tighten_term_for_cube(unsigned i);
bool tighten_terms_for_cube();
void find_feasible_solution();
impq get_cube_delta_for_term(const lar_term& t) const;
bool add_edge_rows_for_term(unsigned i, unsigned x_e);
bool add_cube_edge_rows(unsigned x_e);
lia_move sat_after_rounding();
lia_move round_and_repair();
bool repair_rounded_candidate(vector<flip_candidate>& flips);
public:
int_cube(int_solver& lia);
lia_move operator()();
lia_move find_largest_cube();
};
}

View file

@ -44,7 +44,8 @@ namespace lp {
dioph_eq m_dio;
int_gcd_test m_gcd;
unsigned m_initial_dio_calls_period;
unsigned m_lcube_period;
bool column_is_int_inf(unsigned j) const {
return lra.column_is_int(j) && (!lia.value_is_int(j));
}
@ -52,7 +53,8 @@ namespace lp {
imp(int_solver& lia): lia(lia), lra(lia.lra), lrac(lia.lrac), m_hnf_cutter(lia), m_dio(lia), m_gcd(lia) {
m_hnf_cut_period = settings().hnf_cut_period();
m_initial_dio_calls_period = settings().dio_calls_period();
}
m_lcube_period = settings().m_int_find_cube_period;
}
bool has_lower(unsigned j) const {
switch (lrac.m_column_types()[j]) {
@ -196,6 +198,25 @@ namespace lp {
return m_number_of_calls % settings().m_int_find_cube_period == 0;
}
// The largest cube test is throttled exponentially: when the polyhedron
// does not contain a large enough cube it is unlikely to contain one
// later, after more constraints are added, so each failure doubles the
// period and a success resets it.
bool should_find_lcube() {
return settings().lcube() && m_number_of_calls % m_lcube_period == 0;
}
lia_move find_lcube() {
lia_move r = int_cube(lia).find_largest_cube();
if (r == lia_move::undef) {
if (m_lcube_period < (1u << 30))
m_lcube_period *= 2;
}
else
m_lcube_period = settings().m_int_find_cube_period;
return r;
}
bool should_gomory_cut() {
bool dio_allows_gomory = !settings().dio() || settings().dio_enable_gomory_cuts() ||
m_dio.some_terms_are_ignored();
@ -246,6 +267,7 @@ namespace lp {
++m_number_of_calls;
if (r == lia_move::undef) r = patch_basic_columns();
if (r == lia_move::undef && should_find_cube()) r = int_cube(lia)();
if (r == lia_move::undef && should_find_lcube()) r = find_lcube();
if (r == lia_move::undef) lra.move_non_basic_columns_to_bounds();
if (r == lia_move::undef && should_hnf_cut()) r = hnf_cut();
if (r == lia_move::undef && should_gomory_cut()) r = gomory(lia).get_gomory_cuts(2);

View file

@ -864,7 +864,7 @@ namespace lp {
}
lp_status lar_solver::maximize_term(unsigned j,
impq& term_max) {
impq& term_max, bool fix_int_cols) {
TRACE(lar_solver, print_values(tout););
SASSERT(get_core_solver().m_r_solver.calc_current_x_is_feasible_include_non_basis());
lar_term term = get_term_to_maximize(j);
@ -879,6 +879,11 @@ namespace lp {
return lp_status::UNBOUNDED;
}
if (!fix_int_cols) {
set_status(lp_status::OPTIMAL);
return lp_status::OPTIMAL;
}
impq opt_val = term_max;
bool change = false;

View file

@ -205,7 +205,9 @@ public:
set_column_value(j, v);
}
lp_status maximize_term(unsigned j_or_term, impq& term_max);
// fix_int_cols: after maximizing try to move the integer columns to integer values;
// pass false to keep the optimal (possibly fractional) vertex intact, e.g., for the largest cube test
lp_status maximize_term(unsigned j_or_term, impq& term_max, bool fix_int_cols);
core_solver_pretty_printer<lp::mpq, lp::impq> pp(std::ostream& out) const;

View file

@ -8,6 +8,8 @@ def_module_params(module_name='lp',
('dio_cuts_enable_hnf', BOOL, True, 'enable hnf cuts together with Diophantine cuts, only relevant when dioph_eq is true'),
('dio_ignore_big_nums', BOOL, True, 'Ignore the terms with big numbers in the Diophantine handler, only relevant when dioph_eq is true'),
('dio_calls_period', UINT, 1, 'Period of calling the Diophantine handler in the final_check()'),
('dio_run_gcd', BOOL, False, 'Run the GCD heuristic if dio is on, if dio is disabled the option is not used'),
('dio_run_gcd', BOOL, False, 'Run the GCD heuristic if dio is on, if dio is disabled the option is not used'),
('lcube', BOOL, True, 'use the largest cube test for integer feasibility'),
('lcube_flips', UINT, 16, 'maximal number of coordinate flips when repairing the rounded largest cube center, only relevant when lcube is true'),
))

View file

@ -43,5 +43,7 @@ void lp::lp_settings::updt_params(params_ref const& _p) {
m_dio_ignore_big_nums = lp_p.dio_ignore_big_nums();
m_dio_calls_period = lp_p.dio_calls_period();
m_dio_run_gcd = lp_p.dio_run_gcd();
m_lcube = lp_p.lcube();
m_lcube_flips = lp_p.lcube_flips();
m_max_conflicts = p.max_conflicts();
}

View file

@ -112,6 +112,9 @@ struct statistics {
unsigned m_gcd_conflicts = 0;
unsigned m_cube_calls = 0;
unsigned m_cube_success = 0;
unsigned m_lcube_calls = 0;
unsigned m_lcube_success = 0;
unsigned m_lcube_flip_success = 0;
unsigned m_patches = 0;
unsigned m_patches_success = 0;
unsigned m_hnf_cutter_calls = 0;
@ -152,6 +155,9 @@ struct statistics {
st.update("arith-gcd-conflict", m_gcd_conflicts);
st.update("arith-cube-calls", m_cube_calls);
st.update("arith-cube-success", m_cube_success);
st.update("arith-lcube-calls", m_lcube_calls);
st.update("arith-lcube-success", m_lcube_success);
st.update("arith-lcube-flip-success", m_lcube_flip_success);
st.update("arith-patches", m_patches);
st.update("arith-patches-success", m_patches_success);
st.update("arith-hnf-calls", m_hnf_cutter_calls);
@ -258,7 +264,11 @@ private:
bool m_dio_ignore_big_nums = false;
unsigned m_dio_calls_period = 4;
bool m_dio_run_gcd = true;
bool m_lcube = true;
unsigned m_lcube_flips = 16;
public:
bool lcube() const { return m_lcube; }
unsigned lcube_flips() const { return m_lcube_flips; }
unsigned dio_calls_period() const { return m_dio_calls_period; }
unsigned & dio_calls_period() { return m_dio_calls_period; }
bool print_external_var_name() const { return m_print_external_var_name; }

View file

@ -60,6 +60,14 @@ std::ostream& operator<<(std::ostream& out, const row_strip<T>& r) {
return out << "\n";
}
// Below, static_matrix has a superclass when Z3DEBUG is set, and some
// methods are overrides in that case.
#ifdef Z3DEBUG
#define DEBUG_OVERRIDE override
#else
#define DEBUG_OVERRIDE
#endif
// each assignment for this matrix should be issued only once!!!
template <typename T, typename X>
class static_matrix
@ -119,9 +127,13 @@ public:
void init_empty_matrix(unsigned m, unsigned n);
unsigned row_count() const { return static_cast<unsigned>(m_rows.size()); }
unsigned row_count() const DEBUG_OVERRIDE {
return static_cast<unsigned>(m_rows.size());
}
unsigned column_count() const { return static_cast<unsigned>(m_columns.size()); }
unsigned column_count() const DEBUG_OVERRIDE {
return static_cast<unsigned>(m_columns.size());
}
unsigned lowest_row_in_column(unsigned col);
@ -197,7 +209,7 @@ public:
void cross_out_row_from_column(unsigned col, unsigned k);
T get_elem(unsigned i, unsigned j) const;
T get_elem(unsigned i, unsigned j) const DEBUG_OVERRIDE;
unsigned number_of_non_zeroes_in_column(unsigned j) const { return static_cast<unsigned>(m_columns[j].size()); }
@ -218,8 +230,8 @@ public:
#ifdef Z3DEBUG
unsigned get_number_of_rows() const { return row_count(); }
unsigned get_number_of_columns() const { return column_count(); }
virtual void set_number_of_rows(unsigned /*m*/) { }
virtual void set_number_of_columns(unsigned /*n*/) { }
void set_number_of_rows(unsigned /*m*/) override { }
void set_number_of_columns(unsigned /*n*/) override { }
#endif
T get_balance() const;

View file

@ -97,7 +97,7 @@ expr * datatype_factory::get_almost_fresh_value(sort * s) {
unsigned num = constructor->get_arity();
for (unsigned i = 0; i < num; ++i) {
sort * s_arg = constructor->get_domain(i);
if (!found_fresh_arg && (!m_util.is_datatype(s_arg) || !m_util.are_siblings(s, s_arg))) {
if (!found_fresh_arg && (!m_util.is_datatype(s_arg) || !m_util.are_siblings(s, s_arg) || !m_util.is_recursive(s_arg))) {
expr * new_arg = m_model.get_fresh_value(s_arg);
if (new_arg != nullptr) {
found_fresh_arg = true;
@ -105,7 +105,7 @@ expr * datatype_factory::get_almost_fresh_value(sort * s) {
continue;
}
}
if (!found_fresh_arg && m_util.is_datatype(s_arg) && m_util.are_siblings(s, s_arg)) {
if (!found_fresh_arg && m_util.is_datatype(s_arg) && m_util.are_siblings(s, s_arg) && m_util.is_recursive(s_arg)) {
recursive = true;
expr * last_fresh = get_last_fresh_value(s_arg);
args.push_back(last_fresh);

View file

@ -231,10 +231,8 @@ void func_interp::insert_new_entry(expr * const * args, expr * r) {
m_args_are_values = false;
m_entries.push_back(new_entry);
if (!m_entry_table && m_entries.size() > 500) {
m_entry_table = alloc(entry_table, 1024,
func_entry_hash(m_arity), func_entry_eq(m_arity));
for (func_entry* curr : m_entries)
m_entry_table->insert(curr);
init_table();
ptr_vector<expr> null_args;
null_args.resize(m_arity, nullptr);
m_key = func_entry::mk(m(), m_arity, null_args.data(), nullptr);
@ -243,6 +241,12 @@ void func_interp::insert_new_entry(expr * const * args, expr * r) {
m_entry_table->insert(new_entry);
}
void func_interp::init_table() {
m_entry_table = alloc(entry_table, 1024, func_entry_hash(m_arity), func_entry_eq(m_arity));
for (func_entry *curr : m_entries)
m_entry_table->insert(curr);
}
void func_interp::del_entry(unsigned idx) {
auto* e = m_entries[idx];
if (m_entry_table)
@ -307,6 +311,12 @@ void func_interp::compress() {
if (j < m_entries.size()) {
reset_interp_cache();
m_entries.shrink(j);
if (m_entry_table) {
dealloc(m_entry_table);
m_entry_table = nullptr;
if (m_entries.size() > 500)
init_table();
}
}
// other compression, if else is a default branch.
// or function encode identity.

View file

@ -40,7 +40,7 @@ class func_entry {
// m_result and m_args[i] must be ground terms.
expr * m_result;
expr * m_args[];
expr * m_args[0];
static unsigned get_obj_size(unsigned arity) { return sizeof(func_entry) + arity * sizeof(expr*); }
func_entry(ast_manager & m, unsigned arity, expr * const * args, expr * result);
@ -104,6 +104,8 @@ class func_interp {
void reset_interp_cache();
void init_table();
expr * get_interp_core() const;
expr_ref get_array_interp_core(func_decl * f) const;

View file

@ -513,7 +513,7 @@ void non_auf_macro_solver::collect_candidates(ptr_vector<quantifier> const& qs,
TRACE(model_finder, tout << "considering macro for: " << f->get_name() << "\n";
m->display(tout); tout << "\n";);
if (m->is_unconditional() && (!qi->is_auf() || m->get_weight() >= m_mbqi_force_template)) {
full_macros.insert(f, std::make_pair(m, q));
full_macros.insert(f, {m, q});
cond_macros.erase(f);
}
else if (!full_macros.contains(f) && !qi->is_auf())
@ -524,10 +524,8 @@ void non_auf_macro_solver::collect_candidates(ptr_vector<quantifier> const& qs,
}
void non_auf_macro_solver::process_full_macros(obj_map<func_decl, mq_pair> const& full_macros, obj_hashtable<quantifier>& removed) {
for (auto const& kv : full_macros) {
func_decl* f = kv.m_key;
cond_macro* m = kv.m_value.first;
quantifier* q = kv.m_value.second;
for (auto const &[f, v] : full_macros) {
auto [m, q] = v;
SASSERT(m->is_unconditional());
if (add_macro(f, m->get_def())) {
get_qinfo(q)->set_the_one(f);

View file

@ -203,6 +203,8 @@ namespace array {
ctx.push_vec(d.m_parent_lambdas, lambda);
if (should_prop_upward(d))
propagate_select_axioms(d, lambda);
if (d.m_has_default)
push_axiom(default_axiom(lambda));
}
void solver::add_parent_default(theory_var v) {

View file

@ -219,7 +219,7 @@ namespace smt {
if (use_inv) {
unsigned sk_term_gen = 0;
expr * sk_term = m_model_finder.get_inv(q, i, sk_value, sk_term_gen);
expr * sk_term = m_model_finder.get_inv(q, i, sk_value, *cex, sk_term_gen);
if (sk_term != nullptr) {
TRACE(model_checker, tout << "Found inverse " << mk_pp(sk_term, m) << "\n";);
SASSERT(!m.is_model_value(sk_term));
@ -238,10 +238,6 @@ namespace smt {
TRACE(model_checker, tout << "sk term " << mk_pp(sk_term, m) << "\n");
sk_value = sk_term;
}
// last ditch: am I an array?
else if (false && autil.is_as_array(sk_value, f) && cex->get_func_interp(f) && cex->get_func_interp(f)->get_array_interp(f)) {
sk_value = cex->get_func_interp(f)->get_array_interp(f);
}
}
if (contains_model_value(sk_value)) {

Some files were not shown because too many files have changed in this diff Show more