Repository navigation
Conversation
…ce: run_start The built-in `factory` workflow had drifted from the team skills it drives: - the intent steps ran `factory-product` and `factory-architect`, which ADR-435 replaced with `factory-intent`; - the publish helpers were looked up in factory-mission/scripts/bash, while the team skills moved them to factory-runbook. A missing helper was "skipped" and the step still completed, so a factory run could push nothing, open no MR and still report success. Now: - one `intent` step (`command: factory-intent`, both lanes), one `publish-intent`, then `gate-product` and `gate-architecture` (ids unchanged, both linking the intent MR); - helpers are found in factory-runbook first, factory-mission second; a helper missing from both, or a bash that cannot start, fails its step; - new gate `context.since: run_start` (changes since the run started, ignoring later approvals; merge-base fallback when the run start is not an ancestor). gate-architecture uses it, because the ADRs are written before gate-product is approved and `last_approved` would hide them. Tests: R3 now covers that case (an ADR written before gate-product is still listed at gate-architecture; it fails under `last_approved`); the missing- helper tests assert the step fails with the reason; factory-runbook vs factory-mission lookup; three direct `run_start` tests. 843/843 pass; the node e2e gate passes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kanfil
left a comment
There was a problem hiding this comment.
factory-review verdict: merge-ready (PR #69)
Reviewed revision: head=1fabdc1b772c35bec2a633c4d602c4a76bb04216, base=4e215d61d17720c7e2aa68fd5ac6009485602de6, merge-base=4e215d61d17720c7e2aa68fd5ac6009485602de6 (reviewed from isolated detached checkout).
Scope: 10 files, +219/−91 across src/workflow/builtins.mjs, src/workflow/gate-context.mjs, src/workflow/steps/gate.mjs, and associated test suites/fixtures.
Pass results (REVIEW.md)
| Pass | Severity | Result |
|---|---|---|
| bugs (null/undefined, unhandled errors, resource leaks) | Important | ✅ PASS — fail-closed helper resolution replaces silent skips; run_start gate resolution correctly falls back to merge-base when HEAD has diverged. Full suite (862/862 assertions across 36 suites) passes green. |
| security (injection, secret exposure, auth bypass) | Important | ✅ PASS — shell command generation in helperRun safely serializes directory and file arguments with JSON encoding; no secrets exposed. |
| spec-compliance (PRD/AD coverage) | Important | ✅ PASS — satisfies ADR-435 (intent lane merge) and ADR-469 (factory-intent cutover in adlc-cli builtin). |
| quality (naming, dead code, docs) | Nit | ✅ PASS — Keep-a-Changelog updated, backwards-compatibility fallback to factory-mission preserved for older workspace installs. |
Notes on Architectural Coupling
While this PR is technically sound and necessary to unblock live runs, the underlying design of embedding the factory workflow YAML and inline bash runners inside src/workflow/builtins.mjs is the root cause of this drift. Future work should decouple workflow definitions from CLI binaries by having skills manifest workflow.yml into .adlc/workflows/<id>/workflow.yml during skill installation.
Findings: 0 Important, 0 Nit. Verdict: merge-ready — awaiting human code-owner sign-off.
…n branch between gates Review findings on c1a6dd4: - Important 1: shell steps named `.agents/skills/…`, an install path that is per agent (.claude/skills, …) and absent in this repo. They now call "${ADLC_WORKFLOW_DIR}/scripts/bash/run-helpers.sh" (the engine exports the workflow's directory and keeps it on resume), failing with a reason when it is unset. Copying the workflow elsewhere must copy the skill dir; written down in SKILL.md and the workflow header. - Important 3: a run parked at gate-product can resume in a fresh clone on the base branch, where gate-architecture would diff no ADRs. Restored `run-branch-architecture` between the two gates. - Nit 4: stale "skipped without the helper" comment fixed. - Nit 5: version floor named: adlc-cli newer than 2.7.0 (tikalk/adlc-cli#69). - Nit 6: run-helpers.ps1 has behavioural tests (skip without pwsh); the gate-match test documents `since` as a third intended difference. - Nit 7: SKILL.md states the file runs only by path until shipped workflows are installed into .adlc/workflows/<id>/. Tests: no shell step may name an install path; every shell step's real run line, run from a copy of the skill under .agents/skills and under .claude/skills, finds its helpers; without ADLC_WORKFLOW_DIR it fails with a reason. A hard-coded path fails 4 tests; dropping run-branch-architecture fails the layout test. Engine run (adlc-cli#69) from a .claude/skills layout: run-branch → intent → publish-intent → gate-product, resume → run-branch-architecture → gate-architecture. Important 2 (the skipped → fail reversal of the run-branch amendment) is recorded in the decision-record repository, outside this one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Why
The built-in
factoryworkflow had drifted from the team skills it drives. As a result, a factory run could pass every step and gate, push nothing, open no MR, and still report success.factory(2.4.x – 2.7.0).agents/skills/factory-mission/scripts/bashfactory-runbook/scripts/bashrun-branch,publish-*andopen-mrwere skipped while the step still completed (skipped … (factory-mission helpers not installed)): nothing pushed, no MRcommand: factory-product/factory-architectfactory-intent(ADR-435)ADR-435 calls out this risk ("stale invocations of removed skills"). This file was missed.
Change
src/workflow/builtins.mjs:intent(command: factory-intent, both lanes), then onepublish-intent, thengate-product,run-branch-architectureandgate-architecture.steps.publish-intent.output.mr_url.publish-architectureis removed.run-branch-architecturestays between the two gates: a run parked atgate-productcan resume in a fresh clone on the base branch (restore only writes run state, never the working tree), andgate-architecturediffs the working tree.HELPER_DIRS = [factory-runbook, factory-mission]. Each helper is found in the first directory that has it.src/workflow/gate-context.mjs,steps/gate.mjs: a new gate mode,context.since: run_start.gate-productis approved, sogate-architecturewithsince: last_approvedwould list none of them.gate-architecturenow usesrun_start;gate-productkeepslast_approved.Tests
workflow-gate-context-3): an ADR written by the intent step beforegate-productis still listed atgate-architectureafter the product approval. The test fails withlast_approved(checked).run-branch, and no agent step runs;open-mrmissing →publish-intentfails withopen-mr.sh not found;factory-runbook, or only infactory-mission→ both work.run_start: validation accepts it and still rejects unknown modes; a later approval is ignored; the merge-base fallback works.factory-runbookhelpers for stub runs (tests/fixtures/factory-helpers.mjs).node --test;tests/e2e-node-gate.mjs --skip-agentpasses.workflow validate factoryagainst a workspace with today's team skills: valid, 9 steps.run-branch-architectureran and HEAD is back on the run branch beforegate-architecture.Compatibility
factory-mission) keep working through the fallback.workflow.yml, so a run parked on the old layout keeps the old step IDs.run-branchinstead of completing a run that did nothing. That's intended.🤖 Generated with Claude Code