Skip to content

fix(pe): generate the template manifests instead of hand-writing them - #274

Merged
cryptoxdog merged 3 commits into
mainfrom
claude/pe-pr-repair-remediation-s1iqri
Aug 22, 2026
Merged

fix(pe): generate the template manifests instead of hand-writing them#274
cryptoxdog merged 3 commits into
mainfrom
claude/pe-pr-repair-remediation-s1iqri

Conversation

@claude

@claude claude Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Summary

Mechanical commit subjects (judgment sentence still required):

  • fix(pe): generate the template manifests instead of hand-writing them

Type of Change

  • Bug fix — not measured by open_pr_after_gate.sh — do not treat as verified
  • Feature / enhancement — not measured by open_pr_after_gate.sh — do not treat as verified
  • Refactor (no behavior change) — not measured by open_pr_after_gate.sh — do not treat as verified
  • Documentation — not measured by open_pr_after_gate.sh — do not treat as verified
  • CI / governance change — not measured by open_pr_after_gate.sh — do not treat as verified
  • Breaking change (see rollback plan below) — not measured by open_pr_after_gate.sh — do not treat as verified

Governance Checklist

  • Governance setup verified — ran setup_workspace_symlinks.sh, symlinks resolve (§2) — not measured by open_pr_after_gate.sh — do not treat as verified
  • Symlinks validatedls -la .cursor/rules .cursor/skills .cursor/commands all resolve — not measured by open_pr_after_gate.sh — do not treat as verified
  • All CI gates green — no required checks failing or bypassed — not measured by open_pr_after_gate.sh — do not treat as verified
  • Anti-patterns checked — reviewed CANONICAL_LAW.md §7 — none violated — not measured by open_pr_after_gate.sh — do not treat as verified
  • Protected-path changes authorized — ownership mode is solo_ruleset (CODEOWNERS auto-request is disabled; see CODEOWNERS). Protected-root rewrites carry an ALLOW-ROOT-DELETION: marker and pass the repo gates; CODEOWNERS review applies only when owners are re-enabled — not measured by open_pr_after_gate.sh — do not treat as verified
  • Workspace wiring intact§8 wiring requirements satisfied — not measured by open_pr_after_gate.sh — do not treat as verified
  • TRACEABILITY_MAP.yaml updated — if this PR resolves an open unknown, mark as RESOLVED — not measured by open_pr_after_gate.sh — do not treat as verified
  • Kernel ref discipline — thin callers use @v1, never @main or bare SHA — not measured by open_pr_after_gate.sh — do not treat as verified
  • L4 local autonomy — stacked-branch local commits only during execution; no mid-execution push (§6.2)
  • Post-exec kernels — ran kernels/Recursive Alignment.md then kernels/Validate & Repair.md; l4_local.py authorize-release before this PR

Breaking Change

  • This is a breaking change — not measured by open_pr_after_gate.sh — do not treat as verified

If checked, describe the impact and migration path:

Rollback Plan


Related Issues

Closes #

Commits

  • fix(pe): generate the template manifests instead of hand-writing them

Test plan

  • make pr-check local gate receipt present
  • L4 release receipt present (release_authorized)
  • CI green — not measured by open_pr_after_gate.sh — do not treat as verified

Changed files

  • M .gitattributes
  • M TODO.md
  • M environment/program-execution/core/MANIFEST.yaml
  • M environment/program-execution/core/scripts/generate_manifest.py
  • M ops/scripts/sync_generated_artifacts.py
  • A tests/environment/program_execution/test_core_manifest_shapes.py
  • M tests/ops/scripts/test_sync_generated_artifacts.py

Mechanical evidence

gate-receipt.json present: schema=l9.pr_gate_receipt.v1 head=c5edf2a9a9adac6da769e86813302b82c949e95e passed_at=2026-08-22T02:41:17Z
L4 receipt present: phase=release_authorized head=312cf14dd7f3bc3125ca4971d3d8deeaf3deb2e9


Generated by Claude Code

claude added 3 commits August 22, 2026 02:37
The blueprint and controller templates each carry an integrity manifest that
`validate_pair.py` gates in CI, and nothing regenerated either one. Satisfying
that gate meant hand-writing digest YAML — or running the core generator, which
emitted one fixed shape for all three manifests and so rewrote a template's
`template:` key as `artifact:` and added `bytes:` to every entry, producing a
manifest its own validator rejects.

The generator now reads the shape from the target rather than deciding it: an
existing manifest keeps its top-level keys, their order, and its per-file key
set, and only the digests (and `summary`, where there is one) are recomputed.
`--schema`/`--artifact` are still required to create a manifest that does not
exist yet. One code path now serves all three, and a manifest with a new shape
needs no code change.

`sync_pe_templates` regenerates both under the existing `pe_touched` branch, so
the command governance already mandates — `sync_generated_artifacts.py --force`
— covers them. No new command to learn: the failure mode was running the
documented command and still failing CI.

Both manifests are registered in `GENERATED_PATH_PREFIXES` and attributed to the
`l9-generated` merge driver. They were neither before, which is why they hard-
conflicted on every stacked merge that touched them — including the one that
blocked #263.

TODO.md's "Program Execution MANIFEST.json — advisory by decision" entry is
corrected, not overruled: its claim that nothing in the PR gate or CI enforces
that manifest is stale, because `validate_campaign_promotion.py` hard-fails on
its digests from a test the repo-root suite collects. The contradiction —
declared advisory, so deliberately not auto-generated, while a default-suite
test enforces it — produced the stale-hash failures in #263. Both ways out are
recorded; neither is taken here.

Verified: gate FAIL on an undeclared new file, then PASS after the documented
command, with no hand-editing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FqpeGwrbdAuwq1ZgoMANMZ
Resolves the one conflict, in the generated
environment/program-execution/core/MANIFEST.yaml. Both sides only moved
`summary.total_bytes`, so the resolution is regeneration rather than a hand
pick: main's rewrite of
program-execution-controller-template/scripts/pec/exec_env.py changes that
file's sha256 and byte count, and the rolled-up total with it.

Resolved by taking this branch's side, then running
`ops/scripts/sync_generated_artifacts.py --force` on the merged tree so the
manifest is derived from the merged content. `.l9/pr/regen-required.txt` is
empty and a second regeneration run is a no-op.
`Test Suite` failed on the merge with
test_generated_prefixes_have_not_drifted: this branch adds
program-execution-blueprint-template/MANIFEST.yaml and
program-execution-controller-template/MANIFEST.yaml to
sync_generated_artifacts.GENERATED_PATH_PREFIXES, and main meanwhile grew a
drift check asserting that the git-guardrails copy of that list differs from
the sync script's only by DELIBERATELY_NOT_GENERATED. Neither side conflicts
textually, so the merge was clean and the contract still broke.

Both paths belong in the gate's list rather than the carve-out. They are
generated deterministically by generate_manifest.py — the point of this
branch — and this branch already attributes both `merge=l9-generated` in
.gitattributes, so regeneration is what heals their conflicts. The carve-out
is for paths the sync script touches that no gate-run generator produces
(the hand-authored AUTONOMY_MANIFEST.yaml routing SSOT, and the advisory PE
manifest); these are not that.

Leaving them unregistered would only have made the clean gate treat a
regenerable artifact as user content — noisy, not unsafe — but it would also
have left the two lists out of contract.

tests/ops/autonomy/test_git_guardrails.py: 92 passed.

Remediation-Cycle: #274/cycle-1
@cryptoxdog
cryptoxdog merged commit b13e93c into main Aug 22, 2026
15 checks passed
@cryptoxdog
cryptoxdog deleted the claude/pe-pr-repair-remediation-s1iqri branch August 22, 2026 21:16
cryptoxdog pushed a commit that referenced this pull request Aug 22, 2026
The org auto-seeder recreated this branch on top of main after #274 merged
and force-pushed, which reverted both remediation commits and restored the
stock templates.

Merged its new seed commit rather than force-pushing over it. Both conflicts
were add/add on the two workflows, and the re-seeded copies are byte-identical
to the ones already remediated here (verified: `git diff 2325f08:<path>
40c87c7:<path>` is empty for both, and for .vscode/extensions.json), so
taking this branch's side drops nothing from upstream and keeps:

  - l9-lint-test-node.yml scoped to Biome (no setup-node cache hard-fail, no
    duplicate `Test Suite` required context)
  - semgrep pinned to the AGENTS.md range
  - the identity-map wiring and the two governance artifacts that let the
    strict SDK run succeed

If the seeder recreates this branch again the same reconciliation applies.
Landing it on main is what stops the loop: the seed is missing-only, so it
leaves files that already exist alone.
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.

2 participants