Search by

ignibyte / aic-workflow

chadmandoo

AIC's gated agent workflow: a run per ticket through plan, code, check and complete. Ported from droost-workflow by its author and relicensed MIT. Dev-only.

Package info

github.com/Ignibyte/aic-workflow

Homepage

Issues

pkg:composer/ignibyte/aic-workflow

Statistics

Installs: 5

Dependents: 1

Suggesters: 0

Stars: 0

v0.1.1 2026-11-06 17:40 UTC

This package is auto-updated.

Last update: 2026-11-07 01:48:38 UTC


README

Latest version PHP License Downloads

ignibyte/aic-workflow is a development package. It supplies the app's four-phase engine, code index, scaffolds, independent review and client guards. Runtime code does not depend on it.

Install in an app

Require the package for development, then select the client explicitly:

composer require --dev "ignibyte/aic-workflow:^0.1"
bin/aic workflow:init --client=codex

Omitting --client selects Claude Code. --client=claude is the explicit equivalent. Codex installs .agents/skills/, .codex/agents/aic-seeker.toml, .codex/hooks.json and the committed .codex/aic-workflow.lock. Both clients install the app's workflow settings and managed instructions. Init preserves unrelated hooks and edited owned files. A regular rerun upgrades unchanged owned files. The operator can force a reviewed owned file from a terminal; an open run, malformed settings or an obstructing symlink still refuses before any write.

Commit the installed instructions, role, hooks, settings and lock. This maintainer repository holds the package source, so init refuses here; its own ticket phases remain manual.

Review and launch Codex

The operator reviews the project folder and exact callback definitions in Codex's supported /hooks interface. Trust is tied to the current definitions. Do not bypass that review or edit the trust store. Before launching a fresh session, run this from the operator terminal:

bin/aic workflow:codex-check

The check compares installed instructions and ownership with the package, then asks the real client for enabled, synchronous, trusted callbacks with matching source, event, matcher, command and timeout. Missing responses, configuration errors and stale controls hold launch. A successful process exit without the requested protocol response is insufficient.

The check starts a finite child Codex process. Run it before entering the tool sandbox: the child may need client-state writes that a workspace sandbox refuses. Its failure inside that sandbox does not establish readiness. Restore or review the actual controls and rerun the operator check; do not manufacture a receipt.

Start Codex at the app root. The chosen model and sandbox policy also apply to the native seeker. Apps whose gates need advisory downloads or local Postgres need network access in that workspace policy. Keep database credentials in the environment or the app's supported local configuration, outside committed source.

Keep writable tool state inside the workspace too. The native gates honor ELEPHC_NATIVE_CACHE; Semgrep has separate settings, log and version-cache paths. For a workspace sandbox, set these in the operator terminal before launching Codex:

mkdir -p .native-gate/.cache/semgrep
export ELEPHC_NATIVE_CACHE="$PWD/.native-gate/.cache/elephc-native"
export SEMGREP_SETTINGS_FILE="$PWD/.native-gate/.cache/semgrep/settings.yml"
export SEMGREP_LOG_FILE="$PWD/.native-gate/.cache/semgrep/semgrep.log"
export SEMGREP_VERSION_CACHE_PATH="$PWD/.native-gate/.cache/semgrep/version-cache"

These are disposable tool caches, outside committed source. A gate failure caused by a read-only external cache still holds the run. Repair the tool environment and resume that same run; do not waive the gate or broaden filesystem permissions to hide the failure.

Use $aic-workflow-start and the installed phase skills. One feature uses one ticket and one engine run. The engine runs and records its own gates. At inspection-due, dispatch the native aic-seeker role with Inspect the open run.. File its returned Seeker Inspection section unchanged. A parent-written, changed, stale or duplicate ledger does not replace that return.

Generate components and the first theme

bin/aic command:list includes make:component, make:page, make:layout, make:entity and make:theme. Components live in the theme that config/app.php names (#153): make:component <Class> writes themes/<theme>/components/<Class>/<Class>.php and its lower-kebab .phtml, and edits no manifest. A default make:page writes its own view there and routes the page in its module's manifest; make:page --component=<Class> reuses a theme component. The entity generator's list page uses this shared writer when that generator is implemented.

make:layout <name> (#157) writes a named page layout: src/Layouts/<Case>Page.php, page data with the content region only, and layouts/page--<name>.phtml, and edits no manifest. Its document falls back to html.phtml. After composer run build the generated ThemeLayoutName has the case, and make:page <module> <Class> <path> --layout=<name> passes it; the make refuses a layout the theme does not ship, and --layout with --post. It writes no html--<name>.phtml; write one by hand when a layout needs a document of its own.

make:entity <module> <Class> <table> --fields=<name>:<type>,… [--version=<v>] (#123) writes the entity, <Class>Repository (latest(int)), Create<Table>Table and <Class>ListPage (GET of the table's path, the newest 50 rows as a heading and paragraphs in the framework's atoms), and adds the route and the migration in one manifest edit. Types are text, numeric, date and boolean; a field named id or created_at, a repeated field or an unknown type is a usage refusal. Each body names its entity, so two made entities share no phpcpd run unless about five fields in a row match.

bin/aic make:theme <name> --dry-run --json previews the first theme: src/Layouts/Page.php with four regions, the HTML and page templates in layouts/ and real CSS. It prints the config/app.php, Composer and PHPCS lines to add. Pages take the framework's PageDocuments (#154) and name their title (#187). Use lowercase words joined by hyphens, at most 32 bytes. An existing file refuses before writes; reruns refuse instead of overwriting.

Composer must map "App\\Theme\\Components\\": "themes/<theme>/src/Components/"; run composer dump-autoload before generation. Templates are .phtml and need no mapping: the build escapes each into build/generated/templates/, where a lookup requires it (#155). Makes validate these mappings and do not edit tool configuration. Inspect the dry-run, declare every authored path and the module manifest, and ground those paths with the code index. The ordinary path-based guard checks them all; there is no special exemption for theme or template sources. The engine records code.made. The build owns everything under build/ and the wiki. No generated file is written by a make. Run composer run build after generation.

Measure what the app uses

bin/aic code:coverage (#232) lists every framework surface an app can use (contracts, the kinds' responses, the manifest, Schema and EntityQuery methods, the catalog atoms, the Tessera vocabulary) with the app files that use each, or unused. --missing lists only the unused; --json answers the aic.console/1 envelope. It reads the code index, refreshed first, and exits 0 whatever is unused: it is a report, not a gate. What counts as a use is in the workflow docs.

Read stored gate diagnostics

bin/aic workflow:logs gate:8 reads one stored gate result from the open run, or the latest archived run. It selects the latest matching record unless selectors specify the phase and attempt. Use gate for the aggregate suite output, including abnormal execution and timeouts.

bin/aic workflow:logs gate:8 --phase=code --attempt=1
bin/aic workflow:logs gate --run=run-ID --phase=code --attempt=1 --json
bin/aic workflow:logs gate:8 --from-line=1 --lines=100 --json

Full stored output is the default. JSON uses the existing aic.console/1 envelope and keeps exact transcript bytes when they are valid UTF-8. Plain text remains available for other byte sequences. Explicit line windows preserve original endings and identify the returned range and continuation. JSON also reports total lines and bytes. output_complete describes whether the selection contains every stored byte. transcript_complete separately describes capture provenance: new captures retain all observed output, while historical records report unknown completeness. It does not claim a timed-out process finished or that discarded bytes were recovered.

Each returned record identifies its run, phase, attempt, gate, outcome, fault, subject hash and adjudication time. Freshness is not re-evaluated by inspection. The fixed project database opens with SQLite read-only flags. The command creates no database, migrates no schema, reruns no gate and accepts no SQL or database path. Exit 0 returns stored evidence, exit 1 means unavailable evidence or output, and exit 2 rejects malformed selectors.

A seeker pending beside failed prerequisites was not actionable. Environment-only recovery permits its first inspection-due report. An unchanged repeat of that actionable report still becomes an operator hold. Ordinary repeated faults and retry limits retain their existing behavior.

Amending a frozen row

Planning freezes the spec's criteria, manifest, entry points, decisions and browser items, and every later exit holds on a lost row. When a frozen row is wrong, such as an entry point's status, the operator amends it from a terminal (#267):

bin/aic workflow:amend "<the row as the spec writes it>" "<the new row>" "<why>"

The row must be one whole line of the frozen spec, and the swap must change exactly one frozen row of one section for another; the reason is required. The engine replaces the line in the freeze, which keeps its time and gate list, and in the run's spec, and logs spec.amended with both rows, the reason and the phase. Nothing is frozen at plan, so there it is refused. Like workflow:reset and workflow:answer, it is refused without a terminal and walled from the agent's shell.

What the native guards judge

The adapter reads actual tool and lifecycle fields. It checks every add, update, delete and move destination in a native patch before allowing the tool. Known MCP path fields pass through the same phase, protected-path, vendor and real-destination walls. Unsupported local mutation routes hold. Supported MCP file mutations are write_file and edit_file with explicit non-empty paths; an unknown tool cannot gain permission by supplying a path. A separate native PermissionRequest callback verifies the caller and rechecks supported MCP scope before approving that request. It refuses shell escalation and unknown tools. This project callback does not change global approval or sandbox settings.

Native Bash hooks omit the requested workdir and tty options. After checking the original command, AIC replaces it with an owned runner that starts at the project root and gives its child closed input and no tty. Use an explicit cd in the inspected command for another directory. Later write_stdin input cannot supply the child's commands.

The parent session and actual child id/type bind native review calls to the current run. The seeker's supported edit, shell-write and MCP-write routes refuse. This is workflow policy; the role inherits the parent's client permissions and does not acquire a separate OS sandbox.

Browser looks

Front-end work is looked at with Playwright (#174). Plan refuses a File Manifest that touches a theme (all but the data and text files in its assets/), framework/templates/, tests/browser/, config/app.php, a module's Block/ or Form/, or a Controller/ class not named *Api, unless the spec says browser_testable: Yes and each ## Browser Check item names a look, a Playwright test in tests/browser/. At check the engine runs every named look itself, with vendor/bin/aic-gate browser --base-url=<site> against config/workflow.php's site; the row holds while an item is unticked, a test is missing or a look fails, and waits on the operator when no site is set. At complete each item ends, after saw:, with — keep (the test stays, declared, and gate:23 runs it against the compiled site on every gate run) or — drop (the test is deleted). The app's root package.json and package-lock.json pin Playwright 1.62.1; vendor/bin/aic-gate tools runs npm ci and installs Chromium.

Browser checks in Codex

Configure a trusted Playwright MCP server in the app's Codex configuration. Use an isolated headless browser and a project-local output directory for its automatic logs and downloads. Review that server configuration before launch. AIC inspects tool arguments, not the server's internal implementation or every side effect of a page.

Structured page actions, snapshots and diagnostics are supported for the primary agent at Check, with readable run state and no pending hold. Direct navigation URLs must use the configured app origin. The callback does not inspect redirects or destinations reached by page actions. It is not a browser network sandbox.

A screenshot requires an explicit absolute filename. Declare that artifact in the spec's File Manifest. Every explicit browser artifact filename passes the existing protected, phase, vendor and actual-destination checks. Relative and implicit screenshot destinations are refused. Snapshot and diagnostic results can return directly without a filename. Arbitrary JavaScript evaluation, unsafe Playwright code and file-transfer routes are held. The independent seeker cannot use browser actions.

Use the browser to explore a page while writing its look. The browser row's evidence is the look itself: the engine runs each named Playwright test at Check, so no tool call, copied screenshot or HTTP request stands in for it.

Client limits

Enabled trusted hooks are required for this integration. Codex can continue a tool call when a callback cannot start, times out or returns malformed output. An explicit supported denial blocks the call when the callback runs. AIC emits that denial for its handled tool failures and records review returns only from valid lifecycle events; it cannot turn a client hook-startup failure into an unconditional client refusal. The readiness check and protected controls do not remove this client limit. See the Codex hooks documentation.

The supported client is the local Codex CLI with the native hook and subagent capabilities. Verify another client or execution route before relying on equivalent coverage. A tool's name or a copied event alone is not evidence that a real callback ran.

Source

The ignibyte/aic-workflow repository is a read-only split of workflow/ in Ignibyte/aic-nextgen, made on each release tag. Issues and pull requests go there. MIT licensed.