feat: make structural stack updates fail closed - #36
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b02d515ef8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if source_entry and source_commit != source_entry.get("commit"): | ||
| error( | ||
| findings, | ||
| "base.source_drift", | ||
| f"{base_path.relative_to(ROOT)} pins {source_repository}@{source_commit}, manifest pins {source_entry.get('commit')}", | ||
| ) |
There was a problem hiding this comment.
Reconcile the UCNS base before enforcing the gate
At this commit, running the workflow's exact command fails with base.source_drift: research/ucns/BASE.json pins 1975fe70..., while the manifest pins 828c0b8.... Because this commit also enables the workflow for every changed structural surface, the new required check is red immediately and will block unrelated structural updates until the existing base record and its dependent research are reconciled.
AGENTS.md reference: AGENTS.md:L33-L40
Useful? React with 👍 / 👎.
| - 'research/**' | ||
| - 'libs/**' | ||
| - 'tools/check_stack_consistency.py' |
There was a problem hiding this comment.
Reject unpinned edits to canonical library snapshots
When a PR edits only a tracked file under libs/**, this path starts the consistency job, but the invoked checker never examines the Git diff or any library contents. After the current UCNS baseline failure is repaired, a silent edit to a pinned canonical snapshot will therefore pass unchanged manifests and BASE records, defeating the read-only boundary this workflow is meant to enforce.
AGENTS.md reference: AGENTS.md:L9-L10
Useful? React with 👍 / 👎.
| index[repository] = entry | ||
| for field in (repository, entry.get("commit", ""), entry.get("authority", "")): | ||
| if field and field not in human: | ||
| error(findings, "repository.human_drift", f"STACK_MANIFEST.md is missing {repository!r} projection value {field!r}") |
There was a problem hiding this comment.
Compare repository relations with the human projection
When repositories[*].relation changes, an updater can recompute the digest and copy that digest into STACK_MANIFEST.md while leaving the participant table's relation stale. This loop checks only repository name, commit, and authority, so that machine/human relation drift still passes even though relation changes are explicitly part of the structural transaction.
AGENTS.md reference: AGENTS.md:L33-L36
Useful? React with 👍 / 👎.
| for base_path in sorted(research_root.glob("*/BASE.json")): | ||
| base = load_json(base_path) |
There was a problem hiding this comment.
Require every established workspace to retain its BASE record
When an established workspace's BASE.json is deleted, this glob simply stops visiting that workspace and the checker reports success; for example, after correcting the current UCNS mismatch, deleting research/ucns/BASE.json passes with all manifests unchanged. The workflow therefore permits removing the exact source binding that makes the research workspace interpretable instead of failing the structural update.
AGENTS.md reference: AGENTS.md:L11-L12
Useful? React with 👍 / 👎.
| source_repository = str(base.get("source_repository", "")) | ||
| source_commit = str(base.get("source_commit", "")) | ||
| source_entry = repositories.get(source_repository) | ||
|
|
||
| if source_entry and source_commit != source_entry.get("commit"): |
There was a problem hiding this comment.
Reject BASE records whose source repository is unpinned
When a BASE record names an unknown repository whose final path component still matches the project, source_entry is None, so both the pin comparison and separated-project checks are skipped. For example, changing the UCNS source to Somewhere/ucns with an arbitrary commit passes after the current baseline mismatch is repaired, allowing research provenance to detach silently from every manifest-pinned source.
AGENTS.md reference: AGENTS.md:L11-L12
Useful? React with 👍 / 👎.
| - 'research/**' | ||
| - 'libs/**' | ||
| - 'tools/check_stack_consistency.py' | ||
| - '.agents/skills/stack-update/**' | ||
| - '.github/workflows/stack-consistency.yml' |
There was a problem hiding this comment.
Run the structural gate for root emerging-project changes
When a PR changes only ahbg/**—including deleting or moving that root-level emerging participant—its workspace-specific workflows may run, but this consistency workflow is not created because the path list covers only research/**, libs/**, and named projection files. A structural AHBG change that omits the required manifest and architecture updates can therefore merge without the new fail-closed gate ever executing.
AGENTS.md reference: AGENTS.md:L24-L27
Useful? React with 👍 / 👎.
| --- | ||
| name: stack-update | ||
| description: Fail-closed update protocol for The-Interdependency/stack. Load this when a stack change adds, moves, extracts, graduates, renames, removes, or changes the authority, relation, source identity, or placement of a participant, research workspace, libs pin, BASE record, stack manifest entry, or architecture description; when stack-manifest.json, STACK_MANIFEST.md, README.md, or research BASE.json files may drift from one another; or when validating that a structural stack change is complete before commit or merge. |
There was a problem hiding this comment.
Record the source identity of the vendored skill
This new repo-local skill is described as newer doctrine than the pinned skill-lib/ snapshot, but neither its frontmatter nor any adjacent provenance record identifies the exact source repository commit or a non-transfer boundary. A repo-wide search finds only references to the local path, so agents cannot verify which canonical skill revision governs structural updates or detect local drift from that source.
AGENTS.md reference: AGENTS.md:L21-L22
Useful? React with 👍 / 👎.
|
|
||
| - UCNS has no `LICENSE` file at pinned commit `828c0b8`. | ||
| - EPAC clean install, license, stable release, downstream reconsumption, and authority-transition receipt remain incomplete; `libs/epac/` stays unpopulated until graduation. | ||
| - English Gonol Construction remains stack-local research; independent repository/release authority has not been established. |
There was a problem hiding this comment.
Project the English Gonol hmmm into the machine manifest
This newly added human projection records that English Gonol lacks independent repository/release authority, but stack-manifest.json leaves boundaries.hmmm unchanged and contains no corresponding unresolved item. Because the machine hmmm list is part of the hashed work graph, machine consumers now receive a materially incomplete lifecycle projection even though the human manifest records the limitation.
AGENTS.md reference: AGENTS.md:L33-L36
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8c9b79ac03
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if workspace and workspace not in human: | ||
| error(findings, "research.human_drift", f"STACK_MANIFEST.md does not mention workspace {workspace!r}") | ||
| if commit and commit not in human: | ||
| error(findings, "research.human_drift", f"STACK_MANIFEST.md does not mention research commit {commit!r}") |
There was a problem hiding this comment.
Bind each research participant to its human row
When a structural edit changes the English Gonol participant's repository from stack to EDCM and recomputes/copies the digest, this check still passes because it verifies only the workspace and commit as independent substrings and never compares the repository with the corresponding human-manifest row. The machine work graph can therefore reassign the component to EDCM while STACK_MANIFEST.md still identifies stack as its owner, contradicting the explicit separation boundary. Require a matching participant row rather than unrelated substring presence.
AGENTS.md reference: AGENTS.md:L13-L15
Useful? React with 👍 / 👎.
| project = str(base.get("project", workspace_name)) | ||
| source_repository = str(base.get("source_repository", "")) | ||
| source_commit = str(base.get("source_commit", "")) | ||
| source_entry = repositories.get(source_repository) |
There was a problem hiding this comment.
Reject BASE records that promote research to canon
When a research/*/BASE.json edit changes standing from stack-local-research to canonical, the workflow runs but this function ignores that field and reports success with every manifest unchanged. Consumers of the BASE record then receive a canonical-status claim that directly contradicts the stack's noncanonical research boundary; validate the BASE schema, authority, and standing rather than only its project and source identity.
AGENTS.md reference: AGENTS.md:L11-L12
Useful? React with 👍 / 👎.
| for key in (*HASHED_FIELDS, "work_graph_sha256"): | ||
| if key not in manifest: | ||
| error(findings, "manifest.missing", f"missing required field {key!r}") |
There was a problem hiding this comment.
Enforce the manifest's non-transfer boundaries
When a manifest edit flips boundaries.authority_transfer, proof_status_transfer, or measurement_status_transfer to true, recomputes the digest, and copies that digest into STACK_MANIFEST.md, the checker passes because it requires only that boundaries exists. The machine projection can therefore assert a status transfer while the human manifest continues to prohibit it; validate these boundary values or compare them with the human projection.
AGENTS.md reference: AGENTS.md:L33-L36
Useful? React with 👍 / 👎.
| Also resolve the applicable `interdependent-work-graph` doctrine and, for lifecycle | ||
| transitions, `project-incubation-graduation`. Structural changes are one transaction: |
There was a problem hiding this comment.
Make the required graduation skill resolvable
For extraction or graduation work in a clean checkout, this new mandatory instruction cannot be followed: a repo-wide search finds no project-incubation-graduation/SKILL.md under .agents/, the pinned skill-lib/, or any other repository path, only references to its name. Lifecycle updates therefore depend on unspecified external state instead of the exact reproducible doctrine required by the gate; vendor a provenance-bound copy or identify an available pinned path.
AGENTS.md reference: AGENTS.md:L33-L34
Useful? React with 👍 / 👎.
| - 'research/**' | ||
| - 'libs/**' | ||
| - 'tools/check_stack_consistency.py' | ||
| - '.agents/skills/stack-update/**' |
There was a problem hiding this comment.
Trigger the gate for vendored-skill index changes
When a PR changes only .agents/skills/README.md, neither this pull-request path list nor the equivalent push list starts the consistency job, even though check_stack_update_skill_provenance() explicitly reads that file and would reject a missing or mismatched source commit/blob. The newly added human provenance index can therefore drift from PROVENANCE.json without the intended gate running; include .agents/skills/README.md in both path filters.
AGENTS.md reference: AGENTS.md:L21-L22
Useful? React with 👍 / 👎.
| if manifest.get("schema") != "the-interdependency.stack-manifest": | ||
| error(findings, "manifest.schema", "unexpected or missing stack-manifest schema") |
There was a problem hiding this comment.
Validate the stack-manifest schema version
When stack-manifest.json.version is changed while STACK_MANIFEST.md remains at 1.1.0, this checker still succeeds because it validates only the schema name and the version is also excluded from the digest. A producer can consequently advertise a different schema contract to machine consumers while the human projection and checker continue treating the manifest as the current version; enforce the supported version and its human projection.
AGENTS.md reference: AGENTS.md:L33-L36
Useful? React with 👍 / 👎.
| source_name = source_repository.rsplit("/", 1)[-1] if source_repository else "" | ||
| if project and source_name and project != source_name: | ||
| if (workspace, project) not in research_participant_keys: |
There was a problem hiding this comment.
Enforce former-owner cleanup for every separation
When a new separated workspace other than english-gonol supplies the required participant record and README mention, this generic branch passes even if the source repository's manifest authority still explicitly names the separated project. Only the later English-specific function examines a former owner's authority, so future separations can add a new owner alongside a superseded ownership claim; generalize that cleanup check or declare every recognized separation invariant explicitly.
AGENTS.md reference: AGENTS.md:L33-L36
Useful? React with 👍 / 👎.
Adds a stack-specific structural update guard and repairs the authority/provenance drift that exposed the need for it.
Changes:
stack-updatefromThe-Interdependency/skill-lib@a7b95f891d2e88c62e61524dc52a2e1577c9983dwith exact source bloba1e914893fa047e28d039050395937a1cf6e0138and non-transfer provenance;tools/check_stack_consistency.pyplusstack-consistencyCI;The-Interdependency/ucns@1975fe70cf4e0826a8020c2da3047569e277af64explicit without pretending the olderlibs/ucnspin was refreshed;work_graph_sha256and alignsSTACK_MANIFEST.md,README.md, andAGENTS.md;The checker fails closed on work-graph digest drift, human/machine authority disagreement, unrepresented alternate research bases, separated-component drift, English Gonol ownership regression, and vendored stack-update source/content drift.
Usage:
python tools/check_stack_consistency.pyStanding: English Gonol remains stack-local research, not canon or an independently graduated release. The UCNS alternate base is research provenance only; it does not refresh
libs/ucnsor transfer authority.hmmm: semantic responsibility cannot be inferred exhaustively from source code; a future stack-manifest schema can add typed component and edge records.