Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions .agent-loop/LOOP_STATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

## Current State

- Active initiative: `WS-ENG-001-codex-zero-trust-loop-bootstrap`
- Active chunk: `WS-ENG-001-01`
- Branch: `codex/aztle-codex-bootstrap`
- Status: PR #23 open; internal review complete; external review addressed; CI ready for final rerun; awaiting human merge decision
- Active initiative: none
- Active chunk: none
- Branch: `main`
- Status: `WS-ENG-001-01` merged through PR #23 on 2026-06-20; memory updated; no active chunk
- Merge commit: `b9fe19b96109e9786e1d6d89488abfbe68a05d4a`
- Reviewed code SHA: `b22b940ee50956c9c7bfd0e681ffac727b6ff82c`
- Current gate: human merge checkpoint
- Current gate: stopped after merge memory update
- Next chunk: inactive

## Operating Rule
Expand All @@ -28,4 +29,4 @@ product behavior, database schema, API behavior, or frontend behavior.
- Open sub-agent sessions: none.
- Internal review evidence: `.agent-loop/initiatives/WS-ENG-001-codex-zero-trust-loop-bootstrap/reviews/WS-ENG-001-01-internal-review-evidence.md`
- External review response: `.agent-loop/initiatives/WS-ENG-001-codex-zero-trust-loop-bootstrap/reviews/WS-ENG-001-01-external-review-response.md`
- Final post-review repository changes are limited to evidence/status files.
- PR #23 merged into `main` on 2026-06-20.
8 changes: 6 additions & 2 deletions .agent-loop/REVIEW_LOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

## WS-ENG-001-01

Status: internal reviewer fanout complete.
Status: merged through PR #23 on 2026-06-20.

Merge commit: `b9fe19b96109e9786e1d6d89488abfbe68a05d4a`

Required reviewer tracks:

Expand All @@ -16,6 +18,8 @@ Required reviewer tracks:
- reuse/dedup
- test delta

Result: PASS after fixes.
Result: PASS after fixes; external review addressed; GitHub checks passed.

Evidence: `.agent-loop/initiatives/WS-ENG-001-codex-zero-trust-loop-bootstrap/reviews/WS-ENG-001-01-internal-review-evidence.md`

External review response: `.agent-loop/initiatives/WS-ENG-001-codex-zero-trust-loop-bootstrap/reviews/WS-ENG-001-01-external-review-response.md`
10 changes: 8 additions & 2 deletions .agent-loop/WORK_QUEUE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,17 @@

| Chunk | Title | Risk | Status |
|---|---|---:|---|
| `WS-ENG-001-01` | Codex-native zero-trust loop bootstrap | L1 | In progress |
| None | No active chunk | - | Inactive |

## Completed

| Chunk | Title | Risk | Status |
|---|---|---:|---|
| `WS-ENG-001-01` | Codex-native zero-trust loop bootstrap | L1 | Merged through PR #23 on 2026-06-20 |

## Proposed Next

No next chunk is active. After this bootstrap lands, the next Workstream product
No next chunk is active. After this bootstrap has landed, the next Workstream product
chunk must be planned through the loop and approved by the user before code
starts.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

## Current

- `WS-ENG-001-01`: PR #23 open; internal review complete; external review addressed; CI ready for final rerun; awaiting human merge decision
- `WS-ENG-001-01`: merged through PR #23 on 2026-06-20; complete
- Merge commit: `b9fe19b96109e9786e1d6d89488abfbe68a05d4a`
- Reviewed code SHA: `b22b940ee50956c9c7bfd0e681ffac727b6ff82c`
- Current gate: human merge checkpoint
- Current gate: stopped after merge memory update
- Next chunk: inactive

## Last Update
Expand All @@ -13,10 +14,10 @@ Bootstrap branch created from `origin/main`. Dirty files in the original checkou
were left untouched in their existing branch. Internal reviewer findings were
addressed in the internal evidence artifact. CodeRabbit, GitHub checks, and human
PR feedback were separated into the external review response artifact. Internal
review evidence is bound to the reviewed code SHA, and only evidence/status files
changed after that reviewed revision.
review evidence is bound to the reviewed code SHA. PR #23 is merged, and the loop
memory has been updated on `main`.

## Next Required Event

Push the reviewed revision and evidence/status commit, wait for GitHub checks and
CodeRabbit, then stop for the user-owned merge decision.
No active chunk. Start the next Workstream chunk only after intent, discovery,
plan, chunk map, and chunk contract are approved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Internal Review Evidence: WS-ENG-001 Post-Merge Loop Memory

## Chunk

WS-ENG-001-01

open sub-agent sessions: none

valid findings addressed: yes

## Reviewed Revision

Reviewed code SHA: f4fe5f3c4fbdd626bbc6d3f837aeca1cceb6e9ca

Reviewed at: 2026-06-20T13:15:54Z

Reviewer run IDs: 019ee4bd-d3d5-7830-b042-a46397b2a4f3, 019ee4be-9fd5-78d2-801a-8ccb7541ad19, 019ee4c0-e266-71e3-b65e-3f1afa8af74c, 019ee4c3-8994-7a50-9bb9-49962001a247, 019ee4dd-f49e-72d2-abd4-6391aafe95d3, 019ee4fe-9b01-7741-a130-a4a78f2054b0, 019ee500-050e-7702-99df-a38a87435281, 019ee502-a260-7e01-affe-77867dd21325, 019ee504-e427-76c1-a66f-3fc036207abe

After reviewed SHA `f4fe5f3c4fbdd626bbc6d3f837aeca1cceb6e9ca`, the only committed path changed in this PR is this internal review evidence file. No implementation, workflow, test, policy, or loop-memory state file changed after that reviewed SHA.

## Reviewer Results

| Reviewer | Result | Blocking findings | Notes |
|---|---:|---|---|
| senior engineering | PASS WITH LOW RISKS | None remaining | Confirmed merged-loop memory is no longer stale, the guard is post-merge scoped, and `workflow_dispatch` is low risk because it does not run on PR events. |
| qa/test | PASS | None | Confirmed loop-memory tests use fixtures instead of live checkout state, so valid PR pre-merge memory is not blocked. |
| security/auth | PASS WITH LOW RISKS | None remaining | Confirmed this change touches engineering-loop state and CI only; no Workstream auth, session, token, product runtime, or permission behavior changed. |
| product/ops | PASS WITH LOW RISKS | None remaining | Confirmed post-merge state now says no active chunk, no active PR gate, and future work must start from an approved intent/plan/chunk contract. Low-risk stale wording in `WORK_QUEUE.md` was fixed. |
| architecture | PASS | None | Confirmed the change stays in the Codex engineering loop and does not turn loop state into Workstream product functionality. |
| docs | PASS | None | Confirmed status wording distinguishes merged state, inactive queue state, and external review response logging. |
| ci integrity | PASS AFTER FIXES | None remaining | Confirmed the new main-only loop-memory workflow uses pinned checkout, disabled credential persistence, and a deterministic Python guard. |
| reuse/dedup | PASS | None | Confirmed the guard reuses existing loop files and does not introduce another competing source of truth. |
| test delta | PASS AFTER FIXES | None remaining | Confirmed `scripts/test_agent_gates.py` covers stale pre-merge memory rejection and merged-state acceptance with temporary fixtures. |

## Valid Findings Addressed

- Local Workstream directory confusion: identified `/home/abiorh/flow/workstream` as a separate dirty feature branch, not `main`, and left unrelated checker/test changes untouched.
- Stale merged-loop memory: updated `.agent-loop/LOOP_STATE.md`, initiative `STATUS.md`, `WORK_QUEUE.md`, and `REVIEW_LOG.md` to reflect that PR #23 is merged.
- Missing main enforcement: added the verified workflow path `.github/workflows/loop-memory.yml` so merged loop memory is checked on pushes to `main`.
- Over-broad local-state test risk: changed loop-memory regression tests to use fixture files instead of the live repository state.
- Missing internal evidence for this process change: added this separate internal-review evidence file for PR #24.
- Stale post-merge wording: changed `After this bootstrap lands` to `After this bootstrap has landed` in `.agent-loop/WORK_QUEUE.md`.

## Commands Run

```bash
python3 scripts/check_loop_memory_state.py
python3 scripts/test_agent_gates.py
python3 scripts/check_markdown_links.py
python3 scripts/check_stale_workstream_wording.py
python3 -m py_compile scripts/check_loop_memory_state.py scripts/test_agent_gates.py
git diff --check HEAD~1..HEAD
```

## Remaining Risks

- `/home/abiorh/flow/workstream` remains dirty on `codex/submission-artifact-policy-docs` with unrelated checker/revision testing changes. Those changes were not modified here because they are outside PR #24.
22 changes: 22 additions & 0 deletions .github/workflows/loop-memory.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Loop Memory

on:
push:
branches:
- main
workflow_dispatch:

permissions:
contents: read

jobs:
loop-memory:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
with:
persist-credentials: false

- name: Loop memory state check
run: python3 scripts/check_loop_memory_state.py
79 changes: 79 additions & 0 deletions scripts/check_loop_memory_state.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
"""Validate merged loop memory is not left in a pre-merge state."""

from __future__ import annotations

import re
import sys
from pathlib import Path


ROOT = Path(__file__).resolve().parents[1]
CHECKED_FILES = (
".agent-loop/LOOP_STATE.md",
".agent-loop/WORK_QUEUE.md",
".agent-loop/REVIEW_LOG.md",
)
INITIATIVE_STATUS_FILES = tuple(
str(path.relative_to(ROOT))
for path in (ROOT / ".agent-loop/initiatives").glob("*/STATUS.md")
)
Comment on lines +16 to +19

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Detect missing initiative STATUS.md files explicitly

Line 16–19 only captures existing */STATUS.md files, so an initiative folder missing STATUS.md is silently skipped and never fails validation. That leaves a contract hole in loop-memory integrity checks.

Proposed fix
-INITIATIVE_STATUS_FILES = tuple(
-    str(path.relative_to(ROOT))
-    for path in (ROOT / ".agent-loop/initiatives").glob("*/STATUS.md")
-)
+INITIATIVE_DIR = ROOT / ".agent-loop/initiatives"
+
+def initiative_status_paths() -> tuple[Path, ...]:
+    """Return expected STATUS.md paths for each initiative directory."""
+    if not INITIATIVE_DIR.exists():
+        return ()
+    return tuple(path / "STATUS.md" for path in INITIATIVE_DIR.iterdir() if path.is_dir())
@@
 def checked_paths() -> list[Path]:
     """Return loop memory paths that must not contain pre-merge state."""
     paths = [ROOT / path for path in CHECKED_FILES]
-    paths.extend(ROOT / path for path in INITIATIVE_STATUS_FILES)
+    paths.extend(initiative_status_paths())
     return paths

Also applies to: 49-53, 59-67

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/check_loop_memory_state.py` around lines 16 - 19, The
INITIATIVE_STATUS_FILES variable uses a glob pattern to only capture existing
STATUS.md files, which silently skips any initiative folders that are missing
the required STATUS.md file. To fix this, detect initiative folders in the
.agent-loop/initiatives directory and explicitly verify that each folder
contains a STATUS.md file, raising an error or failing validation if any are
missing. Apply this same validation pattern to all similar glob operations in
the file that are mentioned in the related sections (lines 49-53 and 59-67) to
ensure complete contract enforcement across all loop-memory integrity checks.

FORBIDDEN_PATTERNS = (
(re.compile(r"PR #\d+ open", re.IGNORECASE), "merged main cannot list an open PR"),
(
re.compile(r"awaiting human merge decision", re.IGNORECASE),
"merged main cannot await a merge decision",
),
(
re.compile(r"human merge checkpoint", re.IGNORECASE),
"merged main cannot remain at the human merge checkpoint",
),
(
re.compile(r"CI ready for final rerun", re.IGNORECASE),
"merged main cannot wait for final CI rerun",
),
(
re.compile(r"Push the reviewed revision", re.IGNORECASE),
"merged main cannot instruct pushing reviewed revision",
),
(
re.compile(r"CodeRabbit, then stop for the user-owned merge decision", re.IGNORECASE),
"merged main cannot wait for external review before merge",
),
(
re.compile(r"\|\s*`[^`]+`\s*\|[^|]+\|[^|]+\|\s*In progress\s*\|", re.IGNORECASE),
"merged main cannot keep a completed chunk in active In progress state",
),
)


def checked_paths() -> list[Path]:
"""Return loop memory paths that must not contain pre-merge state."""
paths = [ROOT / path for path in CHECKED_FILES]
paths.extend(ROOT / path for path in INITIATIVE_STATUS_FILES)
return paths


def main() -> int:
"""Fail when loop memory on main still describes a pre-merge checkpoint."""
failures: list[str] = []
for path in checked_paths():
if not path.exists():
failures.append(f"{path.relative_to(ROOT)}: missing loop memory file")
continue
text = path.read_text(encoding="utf-8")
for pattern, message in FORBIDDEN_PATTERNS:
if pattern.search(text):
failures.append(f"{path.relative_to(ROOT)}: {message}")

if failures:
print("Loop memory state is stale:", file=sys.stderr)
for failure in failures:
print(f"- {failure}", file=sys.stderr)
return 1

print("Loop memory state check passed.")
return 0


if __name__ == "__main__":
raise SystemExit(main())
70 changes: 70 additions & 0 deletions scripts/test_agent_gates.py
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,74 @@ def test_stale_wording_patterns_catch_variants() -> None:
assert len(failures) == 2


def test_loop_memory_state_rejects_pre_merge_status() -> None:
"""Main loop memory must not keep pre-merge checkpoint language."""
checker = load_module("loop_memory_state_rejects", "scripts/check_loop_memory_state.py")
original_root = checker.ROOT
original_status_files = checker.INITIATIVE_STATUS_FILES
with tempfile.TemporaryDirectory() as tmpdir:
root = Path(tmpdir)
(root / ".agent-loop/initiatives/example").mkdir(parents=True)
(root / ".agent-loop/LOOP_STATE.md").write_text(
"Status: PR #23 open; awaiting human merge decision\n",
encoding="utf-8",
)
(root / ".agent-loop/WORK_QUEUE.md").write_text(
"| `WS-ENG-001-01` | Bootstrap | L1 | In progress |\n",
encoding="utf-8",
)
(root / ".agent-loop/REVIEW_LOG.md").write_text(
"Status: internal reviewer fanout complete.\n",
encoding="utf-8",
)
(root / ".agent-loop/initiatives/example/STATUS.md").write_text(
"Current gate: human merge checkpoint\n",
encoding="utf-8",
)
checker.ROOT = root
checker.INITIATIVE_STATUS_FILES = (".agent-loop/initiatives/example/STATUS.md",)
try:
with contextlib.redirect_stderr(io.StringIO()):
assert checker.main() == 1
finally:
checker.ROOT = original_root
checker.INITIATIVE_STATUS_FILES = original_status_files


def test_loop_memory_state_accepts_merged_fixture() -> None:
"""Merged loop memory fixtures should pass the main-only guard."""
checker = load_module("loop_memory_state_accepts", "scripts/check_loop_memory_state.py")
original_root = checker.ROOT
original_status_files = checker.INITIATIVE_STATUS_FILES
with tempfile.TemporaryDirectory() as tmpdir:
root = Path(tmpdir)
(root / ".agent-loop/initiatives/example").mkdir(parents=True)
(root / ".agent-loop/LOOP_STATE.md").write_text(
"Status: `WS-ENG-001-01` merged through PR #23; no active chunk\n",
encoding="utf-8",
)
(root / ".agent-loop/WORK_QUEUE.md").write_text(
"| None | No active chunk | - | Inactive |\n",
encoding="utf-8",
)
(root / ".agent-loop/REVIEW_LOG.md").write_text(
"Status: merged through PR #23.\n",
encoding="utf-8",
)
(root / ".agent-loop/initiatives/example/STATUS.md").write_text(
"Current gate: stopped after merge memory update\n",
encoding="utf-8",
)
checker.ROOT = root
checker.INITIATIVE_STATUS_FILES = (".agent-loop/initiatives/example/STATUS.md",)
try:
with contextlib.redirect_stdout(io.StringIO()):
assert checker.main() == 0
finally:
checker.ROOT = original_root
checker.INITIATIVE_STATUS_FILES = original_status_files


def main() -> int:
"""Run all local test functions."""
tests = [
Expand All @@ -709,6 +777,8 @@ def main() -> int:
test_static_sensor_flags_backend_config_as_ci_surface,
test_markdown_link_checker_collects_base_cached_dirty_and_untracked,
test_stale_wording_patterns_catch_variants,
test_loop_memory_state_rejects_pre_merge_status,
test_loop_memory_state_accepts_merged_fixture,
]
for test in tests:
test()
Expand Down
Loading