Skip to content

feat(loop): Phase 0-1 report-only Evidence-Gated Engineering Loop foundation - #7

Merged
brunovicco merged 2 commits into
mainfrom
feat/b2-b3-loop-phase0-foundation
Jul 18, 2026
Merged

feat(loop): Phase 0-1 report-only Evidence-Gated Engineering Loop foundation#7
brunovicco merged 2 commits into
mainfrom
feat/b2-b3-loop-phase0-foundation

Conversation

@brunovicco

Copy link
Copy Markdown
Owner

feat(loop): Phase 0-1 report-only Evidence-Gated Engineering Loop foundation

B2 - Minimal integration in this harness, nothing above 'report' autonomy:

  • protect_sensitive_files.py (template and plugin): deny agent writes to
    '.loop/**' and 'scripts/loop_*', separate from the existing
    secrets denylist, with its own message pointing at docs/LOOPS.md. This
    is the mechanism that keeps loop_runner.py/loop_gate.py/loop_state.py
    and .loop/ contents from being silently built ahead of schedule; only a
    human editing outside of an agent tool call can populate them.
  • template/scripts/_vendor_loop_schemas/: vendored copy of
    engineering-loop-schemas' src/loop_schemas/ (models.py,
    validate_contract.py) at commit 422a8c4, header-documented per file. The
    package is named vendor_loop_schemas (not loop_schemas) so it does not
    collide with its own scripts/loop
    * denylist; that is the one deviation
    from a verbatim vendor, documented in the header and in docs/LOOPS.md.
    Stdlib-only: no new dependency was added to the harness core (PyYAML is
    optional -- JSON contracts always work, YAML degrades gracefully with a
    clear error if PyYAML is not importable).
  • template/scripts/validate_loop_contracts.py: discovers contracts under
    .loop/contracts/**, validates each with the vendored validator, and is
    a documented no-op when none exist (the expected state today). Wired
    into template/scripts/quality_gate.py as a new 'loop-contracts' check.
  • docs/LOOPS.md: the three-tier model (agent/completion/operational), the
    eight final states, the non-negotiable principles, and this repo's
    current state (Phase 1, report-only).

B3 - Report-only self-evaluation workflow, in this harness only (no
changes to the sibling harness in this commit):

  • scripts/loop_self_evaluation.py: renders every profile x governance
    combination into a temporary directory (discarded after the run), gates
    each with its own quality_gate.py, checks manifest/plugin/documentation
    consistency by delegating to tests.test_harness.DistributionTests, and
    writes a structured report.json + report.md. Zero repository
    modification; exit code reflects whether everything passed.
  • .github/workflows/loop-self-evaluation.yml: workflow_dispatch (with a
    default-false 'run_agent_interpretation' input whose step is an inert,
    read-only placeholder defining no credentials) plus a weekly schedule.
    Uploads the report as a build artifact. Security: top-level
    'permissions: {}', explicit job-level 'contents: read' only,
    'persist-credentials: false', every action pinned by full commit SHA,
    no pull_request_target anywhere.

Out of scope, per the approved plan: no loop_runner.py, loop_gate.py,
loop_state.py, evaluator, or state machine; no autonomy above 'report'.

Validation: full 'uv run python -m unittest discover -s tests -v' (61
tests) passed; ruff check/format clean; mypy clean on the covered source
roots (scripts/loop_self_evaluation.py additionally checked standalone
with mypy --strict, clean; it is not yet in the repo-level mypy path,
which pre-dates this change and covers bootstrap.py/tests/template only);
scripts/quality_gate.py passed in full prior to this commit's final
additions, with every subsequent addition verified individually (ruff,
mypy, and the full test suite including the new, slower self-evaluation
end-to-end test) since the sandbox's command timeout could not host one
single >45s invocation of the full gate.

…ndation

B2 - Minimal integration in this harness, nothing above 'report' autonomy:

- protect_sensitive_files.py (template and plugin): deny agent writes to
  '.loop/**' and 'scripts/loop_*', separate from the existing
  secrets denylist, with its own message pointing at docs/LOOPS.md. This
  is the mechanism that keeps loop_runner.py/loop_gate.py/loop_state.py
  and .loop/ contents from being silently built ahead of schedule; only a
  human editing outside of an agent tool call can populate them.
- template/scripts/_vendor_loop_schemas/: vendored copy of
  engineering-loop-schemas' src/loop_schemas/ (models.py,
  validate_contract.py) at commit 422a8c4, header-documented per file. The
  package is named _vendor_loop_schemas (not loop_schemas) so it does not
  collide with its own scripts/loop_* denylist; that is the one deviation
  from a verbatim vendor, documented in the header and in docs/LOOPS.md.
  Stdlib-only: no new dependency was added to the harness core (PyYAML is
  optional -- JSON contracts always work, YAML degrades gracefully with a
  clear error if PyYAML is not importable).
- template/scripts/validate_loop_contracts.py: discovers contracts under
  .loop/contracts/**, validates each with the vendored validator, and is
  a documented no-op when none exist (the expected state today). Wired
  into template/scripts/quality_gate.py as a new 'loop-contracts' check.
- docs/LOOPS.md: the three-tier model (agent/completion/operational), the
  eight final states, the non-negotiable principles, and this repo's
  current state (Phase 1, report-only).

B3 - Report-only self-evaluation workflow, in this harness only (no
changes to the sibling harness in this commit):

- scripts/loop_self_evaluation.py: renders every profile x governance
  combination into a temporary directory (discarded after the run), gates
  each with its own quality_gate.py, checks manifest/plugin/documentation
  consistency by delegating to tests.test_harness.DistributionTests, and
  writes a structured report.json + report.md. Zero repository
  modification; exit code reflects whether everything passed.
- .github/workflows/loop-self-evaluation.yml: workflow_dispatch (with a
  default-false 'run_agent_interpretation' input whose step is an inert,
  read-only placeholder defining no credentials) plus a weekly schedule.
  Uploads the report as a build artifact. Security: top-level
  'permissions: {}', explicit job-level 'contents: read' only,
  'persist-credentials: false', every action pinned by full commit SHA,
  no pull_request_target anywhere.

Out of scope, per the approved plan: no loop_runner.py, loop_gate.py,
loop_state.py, evaluator, or state machine; no autonomy above 'report'.

Validation: full 'uv run python -m unittest discover -s tests -v' (61
tests) passed; ruff check/format clean; mypy clean on the covered source
roots (scripts/loop_self_evaluation.py additionally checked standalone
with mypy --strict, clean; it is not yet in the repo-level mypy path,
which pre-dates this change and covers bootstrap.py/tests/template only);
scripts/quality_gate.py passed in full prior to this commit's final
additions, with every subsequent addition verified individually (ruff,
mypy, and the full test suite including the new, slower self-evaluation
end-to-end test) since the sandbox's command timeout could not host one
single >45s invocation of the full gate.
@brunovicco
brunovicco force-pushed the feat/b2-b3-loop-phase0-foundation branch from 5508333 to a8a4352 Compare July 18, 2026 15:30
Re-vendor _vendor_loop_schemas/{__init__,models,validate_contract}.py
from brunovicco/engineering-loop-schemas@75a63ee,
which fixes two lint failures surfaced by CI on this branch's
generated-profiles (3.14, library) job:

1. UP037 flagged models.py's load-bearing quoted self-referencing
   from_dict return annotations as removable, assuming PEP 649
   semantics whenever target-version=py314 -- wrong here, since this
   file also has to support 3.12/3.13 where the quotes are required.
   Fixed upstream via a per-file-ignore in engineering-loop-schemas'
   own pyproject.toml, not an inline noqa (an inline noqa becomes a
   *second* failure, RUF100 unused-directive, on 3.12/3.13). Added the
   matching per-file-ignore here: template/pyproject.toml,
   profiles/library/pyproject.toml, profiles/workspace/pyproject.toml
   (service has no override pyproject.toml and inherits the template's).

2. A stray '# noqa: PLC0415' on validate_contract.py's lazy
   'import yaml' was itself unused (no consumer selects ruff's PL
   rules) and became a second RUF100 failure once vendored into a
   project with RUF enabled. Dropped upstream.

Verified by rendering all three profiles (service, library, workspace)
at Python 3.12/3.13/3.14 and running their quality gates, re-running
the full 68-test suite, and re-running scripts/loop_self_evaluation.py
end to end -- all pass.
@brunovicco
brunovicco marked this pull request as ready for review July 18, 2026 16:01
@brunovicco
brunovicco merged commit ad65208 into main Jul 18, 2026
13 checks passed
@brunovicco
brunovicco deleted the feat/b2-b3-loop-phase0-foundation branch July 18, 2026 16:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant