docs(spec): retain the inactive OpenAPM v0.2 foundation - #2820
docs(spec): retain the inactive OpenAPM v0.2 foundation#2820Daniel Meppiel (danielmeppiel) wants to merge 48 commits into
Conversation
Centralize local scope admission in user_scope_rejection_reason and retain declaring-local-parent source context in resolution and materialization. Keep direct relative inputs rejected and existing containment boundaries unchanged. Add production-boundary and installed-CLI regression/control coverage, architecture ownership guardrails, and focused docs. Fixes #2815. Phase 2 follow-up to #2813; the separate normative discrepancy is tracked in #2818. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The admission change is centralized in the stated owner, correctly threaded through both production call sites, and is pinned by unit, component, e2e, and architecture-guard regression coverage.
Review tier: Lite
Findings: None
What changed in this PR
Fixes a user-scope (apm install --global) resolution/materialization gap where a local package’s relative transitive local dependency (e.g. ../child) could be silently omitted; the fix centralizes admission policy in user_scope_rejection_reason and threads proven declaring-parent context through both resolve-time and acquire-time paths.
Changes:
- Extend
user_scope_rejection_reasonto allow relative local transitive deps at USER scope only when anchored by a resolver-proven local parent with an absolute source directory. - Replace inline USER-scope local-path rejection in both resolver callback and
LocalDependencySource.acquirewith owner delegation (and parent context). - Add unit + integration regressions, plus architecture-linter guard + mutation proving parent-context forwarding stays enforced; update CLI/docs guidance accordingly.
| File | Description |
|---|---|
src/apm_cli/install/package_resolution.py |
Expands the canonical USER-scope admission owner to optionally accept anchored transitive relative locals when provided declaring-parent context. |
src/apm_cli/install/phases/resolve.py |
Routes resolver callback admission through user_scope_rejection_reason(dep_ref, scope, parent_pkg=...) instead of an inline predicate. |
src/apm_cli/install/sources.py |
Retrieves the actual graph parent for local deps (when annotated) and delegates USER-scope admission to the owner; reuses owner reason in diagnostics. |
tests/unit/install/test_user_scope_rejection_reason.py |
Unit coverage for the new anchored-admission case and for rejecting missing/remote/unanchored parent contexts. |
tests/unit/install/test_local_scope_admission.py |
Component-level boundary tests proving both resolve and acquire paths preserve the local declaring-parent anchor at USER scope. |
tests/integration/test_global_local_transitive_dependency_e2e.py |
Installed-CLI regression/control matrix for project vs global scope and relative vs absolute child refs; verifies reinstall parity and direct-relative rejection. |
scripts/architecture_linter/checks/install_request_and_source.py |
Adds a guard ensuring local USER-scope admission routes through the owner and that parent context is forwarded where required. |
scripts/architecture_linter/checks/install_deployment_analyzers.py |
Registers the new guard in the install-deployment architecture rule catalog. |
tests/integration/test_architecture_owner_rule_mutations.py |
Adds a mutation case proving the guard fires if resolver drops parent_pkg context when calling the owner. |
.apm/architecture/owners/install-deployment.json |
Registers “Local dependency admission at user scope” as owned by user_scope_rejection_reason. |
docs/src/content/docs/reference/cli/install.md |
Documents the --global distinction: direct locals must be absolute; transitive relative locals resolve from declaring parent’s original source dir. |
packages/apm-guide/.apm/skills/apm-usage/commands.md |
Mirrors the same --global path semantics in shipped command guidance. |
packages/apm-guide/.apm/skills/apm-usage/dependencies.md |
Updates the local-path anchoring rule to explicitly cover user scope and the “known parent anchor required” constraint. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Keep the exact semantic inventory contract in sync with the new #2815 admission guard. Reproduces and fixes the Linux CI shard failure without weakening the inventory assertion. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
Follow-up The only failing check on the current head is Spec conformance / Mode B: 35 substantive install-path additions require a corresponding spec artifact or explicit waiver. The existing conformance tests themselves passed locally (197 passed, 2 skipped), but that does not satisfy or waive the Mode B gate. #2818 records the maintainer-approved behavior ruling and separate specification follow-up. However, CONTRIBUTING documents the ordinary waiver for changes with no observable behavior delta; this bug fix does change observable behavior. An explicit exception or reviewed specification reconciliation is still needed. No waiver, detector change, speculative spec edit, or automatic merge has been applied. The original #2813 parity regression and controls ran unchanged against this worktree installed CLI: all three passed. The archived regression file hash matched its published commit exactly ( |
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Replace the waived req-mf-016 claim with explicit source anchors and separate remote/internal-symlink containment rules. Keep restricted-root consumer policies permitted and record the single-amendment public-comment exception without changing Section 9. Add executable conformance controls and forced rematerialization from the written local lock. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Fold guardian technical feedback without activating a new specification version: distinguish syntactic local paths from remote-derived Git references; cover USER remote sibling/escape routing, multihop local anchors, and missing-anchor other-scope decoys. Preserve pending compatibility adjudication. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Remote repositories named _local/parent must remain remote. Project transient source kind from the actual parsed acquisition route across every resolver load path without contaminating cached manifests. Fail closed at loader and acquisition boundaries when transitive local provenance is absent or non-local, preserving direct local selection and same-repository remote expansion. Cover PROJECT and USER relative/absolute refusal, genuine local and remote controls, source layouts, cache isolation, and architecture ownership. Keep specification version activation with the coordinator. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Local Wave 2 working snapshot, not a publishable candidate. Preserve the previous minor and unchanged schemas; select the distinct corrective draft, keep reserved features inactive, and bind fresh collection to exact revision metadata. Audit-owner wording and immutable production integration remain pending. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Integrate c457d91 without rewriting source authorship. Keep its normative correction in the distinct v0.2.0 draft, retain the previous minor byte-for-byte except the informative notice, and regenerate selected-revision bindings. Audit-owner input remains pending; not a publication candidate. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keep the canonical matrix's established-source-kind mutation and preserve the earlier declaring-parent delegation mutation as a separate behavioral guard. This resolves the exact-once inventory collision from integrating the immutable provenance fix without dropping either assertion. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Use manifest targets, saved configuration, then existing audit detection without inferring historical install overrides from ownership. Reuse live target profiles in warm and cold replay, fail unavailable intent explicitly, and keep old file and directory claims in comparison after target contraction. Add hermetic source-CLI and component regressions, authority mutations, and audit/config documentation. No lockfile schema or experimental manifest changes. Fixes #2816 Refs #2813 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Reject malformed current target intent, isolate or refuse native replay, retain contracted native claims for comparison, and keep audit configuration reads non-creating. Add real CLI boundary controls without modifying published v0.1 conformance. Refs #2816, #2813. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Integrate the audit owner's exact current-intent and read-only replay contract as req-lk-023. Move all 30 original CLI controls without changing their executable AST; bind the 29 replay cases to the new requirement and the invalid-owner control to req-pl-016. Preserve req-lk-017's inherited obligation and disclose the reference CLI's bare-audit baseline gap instead of silently weakening it. Retain the prior minor indefinitely, reuse all wire schemas, keep reserved features inactive, and generate a 122-entry exact-revision static binding inventory. This is an immutable review candidate, not publication or ratification; latest remains unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Apply formal round-2 synthesis F1/F3/F6/F7/F9/F10 only: audit-scoped explicit selection, local-content replay composition, directory-claim membership, retained schema and Git-tree evidence limitations, and exact citation wording. Preserve all IDs, old artifacts, schemas, and inherited integrity obligations. Integration owner retains companion tests, limitations, report regeneration, and publication. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Add saved explicit-only target and retained schema-boundary companions. Record the precise inherited internal-resource replay failure with a strict, exception-scoped expected failure after integrity and live-state assertions, plus an unsuppressed escaping-link refusal control. Regenerate exact-version bindings and document limitations without weakening normative requirements or production boundaries. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keep the selected manifest note truthful after adding explicit-only and narrowly expected-failing replay companions. Regenerate exact manifest fingerprints; no normative or runtime change. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
APM Spec Guardian:
|
| Work | Final disposition |
|---|---|
| F1-F4 role applicability | Existing secondary-role clauses enumerated; primary tuples and 124 IDs unchanged. |
| F5-F7 wording and citation | Descriptive lowercase wording and the host-class alias link corrected; operative duties retained. |
| F8 attestation trust boundary | Informative trusted-record assumption; verification/enforcement remain reserved. |
| F9 canonical-byte limitation | Disclosure folded; encoding finding remains unresolved. |
| Schema identity | sw-rec-r3-2, pkg-blk-r3-1, tag-blk-r3-1 closed by exact upstream 5a0 plus final reconciliation. |
Exact-head evidence and human boundary
At this head: 276 functional/active-version passes and 2 existing skips; 24 registered owner mutation passes; all seven canonical lint categories and architecture boundaries passed. Strict owner-touch v2 verification covers all four actual-main owners. All 11 guardian mechanical checks passed, including all six schemas and 124/119/5 counts. The site build passed with 1,052 relative links. These are not the #2919 complete inactive-v0.2 assessment or human review.
Hosted CI: all seven pull-request workflows and the push setup workflow succeeded at this exact head. CI, spec conformance, docs, CodeQL, CRLF, NOTICE, gate workflow. Docs deployment itself was skipped for the PR; build success is not live normative publication. GitHub reports MERGEABLE, but the PR remains draft and its human requirements remain unsatisfied.
Section 9.3 still requires two distinct non-author humans: one with implementation experience and one with consumer/integrator experience. Each should record the exact SHA, relevant experience role, evidence examined and actual decision. #2901's 14-day public-comment period follows that qualifying pair; no start or exception is assumed. The recorded #2818 exception omits only this corrective amendment's public-comment period, not its qualified reviews, conformance, acceptance or migration duties. Section 9.5's 90-day announcement-to-removal period is separate and has not started merely because this draft exists. The PR body gives the exact human procedure. No human decision is supplied by this panel.
Historical round-3 convergence
The table below remains the actual d221 review, not current open-issue counts. Its three highest-severity reports covered two underlying defects; two independent reports concerned the now-repaired schema identity defect. No scores, findings or synthesis were retroactively changed.
| Panel | Stance | Shocked | New B | New R | New N |
|---|---|---|---|---|---|
| spec-swagger-editor | ship_with_followups | 8/10 | 0 | 2 | 2 |
| spec-oci-editor | needs_next_brief | 7/10 | 1 | 1 | 0 |
| spec-pkgmgr-editor | needs_next_brief | 7/10 | 1 | 0 | 0 |
| spec-tag-architect | needs_next_brief | 8/10 | 1 | 0 | 0 |
B = highest-severity findings; R = recommended; N = nits.
Convergent themes (historical)
- T1 -- Preservation against prospective fix(alias): reject path-traversing dependency aliases — fixes #2900 #2901 does not preserve the already-public immutable schema identities. (sw-rec-r3-2, pkg-blk-r3-1, tag-blk-r3-1).
Original round-3 synthesis and exact fold instructions
At immutable d22119c, the four actual round-3 returns total 3 blocking, 3 recommended and 2 nit findings. The mean is (8 + 7 + 7 + 8) / 4 = 7.5. The blocker veto therefore requires next_brief, notwithstanding Swagger's ship_with_followups stance or the two duplicate reports of the schema-identity defect. The inactive foundation preserves substantial local-source, audit and version-routing work, but its integrated candidate inherits #2901 changes to two already-public byte-immutable schema resources. TAG's live HTTP observations and the package-manager validation counterexamples prevent a preservation claim based only on prospective ancestry. Sole #2901 owner 265f already owns the versioned-ID repair; do not usurp that work. After that repair is available, reanchor #2820 and reconcile its citations and provenance against the exact new prerequisite, actual main and the published identities, rather than declaring this reviewed SHA repaired.
Continue the authorized engineering work on the inactive foundation and apply the bounded documentation folds, but do not call the result ready to ship while the actual blocking findings remain. OCI separately demonstrates inherited non-injective LF-delimited canonical Git-tree encoding, not a defect caused by the local-source/audit correction and not a proven CLI exploit. Its informative disclosure is appropriate now but supplies neither a fix nor a normative waiver; commission a separately authorized canonical-byte brief before choosing an LF ban or a versioned encoding remedy. Historical round caps are not the reason for this recommendation and do not end the user-authorized continued engineering. #2919 retains executable assessment and bindings; #2923 retains aggregation. This synthesis is advisory preparation, not runtime conformance, publication, latest promotion or ratification. Two distinct qualified non-author human reviews and the applicable amendment obligations remain outstanding; the #2818 exception omits only that amendment's public-comment period and grants no exception for #2901 or this new canonical-byte decision.
[F1 / standalone] docs/src/content/docs/specs/openapm-v0.2.md, Section 4.9
For sw-rec-r3-1, move req-ext-002 from the Consumer summary to Producer. Add req-mf-001 to Consumer and a Consumer SHOULD reference to req-mf-004, limited to its existing Consumer validation clause. Preserve the Producer references and all requirement bodies; this enumerates existing applicability rather than adding obligations.
Success criterion: Within Section 4.9, req-ext-002 appears only under Producer; req-mf-001 appears under both roles; req-mf-004 appears as SHOULD under both roles, with Consumer applicability explicitly limited to its existing clause. All links resolve, and the requirement anchor set is unchanged.
[F2 / standalone] docs/src/content/docs/specs/openapm-v0.2.md, Section 11.1
For sw-rec-r3-1, clarify in the section-summary paragraph that Appendix C and the informative inventory record primary index classification, not exclusive role applicability. Qualify the Appendix-C-wins sentence as a rule for primary classification; explain that a primary class does not exempt a second role expressly bound by the existing requirement body. Keep the four classes, requirement bodies, primary-class tuples and inventory format unchanged.
Success criterion: Section 11.1 explicitly distinguishes primary classification from secondary roles named in requirement text. Its Appendix-C precedence sentence no longer implies an exemption for those roles. No requirement ID, primary-class value, schema field or operative requirement is introduced or removed.
[F3 / standalone] docs/src/content/docs/specs/openapm-v0.2.md, Section 11.3.1
For sw-rec-r3-1, add Producer enumeration links to req-sc-007 and req-cf-002. Identify their existing Producer secret-pattern packing and conformance-claim duties without importing Consumer-only clauses. Do not alter the requirement bodies or their primary index classifications.
Success criterion: Section 11.3.1 contains exactly one resolving enumeration link for each added ID. req-sc-007 and req-cf-002 remain in the Consumer enumeration and retain their original operative text and primary index entries.
[F4 / standalone] docs/src/content/docs/specs/openapm-v0.2.md, Section 11.3.2
For sw-rec-r3-1, add req-mf-001 and the Consumer SHOULD clause of req-mf-004 to the Consumer enumeration. Retain their Producer enumeration entries and make clear that the second reference identifies the already-written Consumer clause, not an additional requirement.
Success criterion: Section 11.3.2 contains resolving links to req-mf-001 and req-mf-004, with the latter identified as SHOULD. Their Producer entries remain. Unique anchor and Appendix C row totals remain 124, including 119 MUST and 5 SHOULD; cross-role references do not increase those totals.
[F5 / standalone] docs/src/content/docs/specs/openapm-v0.2.md, Section 6.3.1
For sw-nit-r3-1, replace 'Exact packages every consumer manifest must include' in the require-field table with 'Exact packages required in the consumer manifest'. In req-pl-018(e)'s descriptive policy-author sentence, replace 'must enumerate those spellings' with 'need to enumerate those spellings'. Preserve the req-pl-018 citation and every operative uppercase clause.
Success criterion: Both original lowercase-must phrases are absent from Section 6.3.1 and both replacements are present. Its uppercase normative statements, requirement anchors, matching rules and deny precedence are unchanged.
[F6 / standalone] docs/src/content/docs/specs/openapm-v0.2.md, Section 10.8
Complete sw-nit-r3-1 by replacing 'policy authors must enumerate the spellings' with 'policy authors need to enumerate the spellings' in the case-sensitive-source guidance. Leave the mitigation references and policy semantics unchanged.
Success criterion: The guidance in Section 10.8 contains 'policy authors need to enumerate the spellings', not the original lowercase-must phrase; no other mitigation wording or link changes in this fold.
[F7 / standalone] docs/src/content/docs/specs/openapm-v0.2.md, Section 10.3 / req-sc-003
For sw-nit-r3-2, replace only the 'alias-extended via' link label and fragment from req-sc-006 to req-sc-005. Preserve every credential-isolation, redirect and diagnostic obligation.
Success criterion: The alias-extension citation in req-sc-003 resolves to req-sc-005, the host-class alias rule. Its remaining text is byte-identical to the reviewed candidate, and unrelated req-sc-006 references remain intact.
[F8 / standalone] docs/src/content/docs/specs/openapm-v0.2.md, Section 10.12
For oci-rec-r3-1, add one explicitly informative paragraph: digest comparisons assume a trusted expected digest or lockfile and do not authenticate simultaneous replacement of record and payload. Describe the reserved attestation subject as canonical package/source identity and version, applicable archive or Git-tree content digest, and publisher identity. Explain that trust-root selection, verification policy and an interoperable envelope require separately scoped design. Keep attestation verification and enforcement reserved; do not suggest that a trusted expected digest repairs the distinct Git-tree encoding defect.
Success criterion: The paragraph names the trusted-record assumption, simultaneous replacement, all proposed future subject components and the three deferred design choices. It adds no wire field, signature requirement, activation or exception to an integrity obligation, and does not assert that trusted records make the existing Git encoding injective.
[F9 / standalone] docs/src/content/docs/specs/openapm-v0.2.md, Section 5.6.4
For oci-blk-r3-1, add an explicit informative limitation stating that the retained LF-delimited encoding permits distinct trees to have identical canonical bytes when a filename contains LF, without a SHA-256 collision. Identify this as newly demonstrated inherited specification debt, not a local-source/audit regression or a demonstrated reference-CLI exploit. State that a separately authorized normative canonical-byte brief is required and disclosure does not repair the defect or waive req-lk-015. Qualify the later editorial phrase 'providing collision-resistant integrity' by pointing to this unresolved encoding defect. Preserve the grammar and compute/record/verify/fail-closed obligations verbatim; do not add a filename ban, escaping rule or replacement encoding.
Success criterion: Section 5.6.4 explicitly identifies LF filename ambiguity and distinct trees with equal canonical bytes, calls for separately authorized normative work, and retains non-waiver and no-runtime-proof boundaries. Its later editorial note no longer asserts unqualified collision resistance. The canonical grammar and req-lk-015 operative body are byte-identical to the candidate. oci-blk-r3-1 remains counted as an unresolved blocking finding after this disclosure.
Original scope dispositions
sw-rec-r3-2 -- Decline a #2820-owned upstream schema fix, not the finding. This corroborates T1 and is assigned to sole #2901 owner 265f for distinct versioned schema identities. That owner preserves already-public bytes and updates its amendment references. The foundation is then reanchored with accurate inheritance and Appendix A citations; no corrected prerequisite SHA or completed repair is asserted here.
pkg-blk-r3-1 -- Uphold the blocker and its alias '.' schema-boundary counterexample. Decline only independent upstream edits or a patch-release deferral disguised as resolution. #2901 owner 265f owns the versioned-ID repair; #2820 does not rewrite those files or weaken unsafe-alias refusal. Preserve the existing public schema bytes and identities and use distinct filenames and $ids for revised validators. The original blocking count remains one for this panel, even though TAG independently reports the same underlying defect.
tag-blk-r3-1 -- Uphold the blocker. TAG reports live HTTP 200 schema bytes matching actual main and different candidate bytes under unchanged $ids, plus an alias '..' validation counterexample. This is stronger publication evidence than prerequisite-relative equality and is not independently refetched in this synthesis. Decline a separate local repair, an assertion that the old URLs were unpublished, or an implied human waiver. Route the already-assigned versioned-ID work to #2901 owner 265f; retain this panel's independent blocking count and require exact replacement-ancestry evidence before claiming reconciliation.
oci-blk-r3-1 -- Uphold the newly demonstrated inherited encoding blocker; reject applying either an LF-name rejection rule or a changed canonical encoding as an unapproved editorial fold. OCI's two-file tree a='first payload', b='second payload' and one-file tree named 'a ' + SHA256('first payload') + LF + '100644 b', containing 'second payload', yield the same specified canonical bytes without a SHA-256 collision. No CLI exploit is established. F9 discloses but does not resolve this defect. A separately authorized normative canonical-byte brief must choose and version the remedy, define compatibility, and retain the counterexample for separately owned conformance work. Neither continued engineering authorization nor the #2818 public-comment exception authorizes that decision. No existing reserved-slot anchor is established for this repair; do not invent one. The defer_v0_2 schema also combines a closed fold_item with an additional required reserved_slot_anchor, so no valid nonempty entry can express this work. Its empty array is a schema-compatible representation, not a risk dismissal or permission to ship.
Full per-panel findings at d221
spec-swagger-editor -- 8/10, confidence high
At immutable d22119c, the inactive corrective foundation closes the historical Swagger folds and has no new blocking interface-contract finding. Schema metaschemas, references, discriminator boundary probes, inventory counts, inherited numbering and static version routes check out, subject to the explicitly disclosed legacy schema limitations and the cross-class enumeration and prerequisite schema-identity followups above. This is an engineering advisory for the inactive foundation, not runtime qualification, publication authorization or human ratification.
Recommended findings (2)
[sw-rec-r3-1] openapm-v0.2.md Sections 4.9, 11.1, 11.3.1-11.3.2 and Appendix C; req-mf-001, req-mf-004, req-sc-007, req-cf-002 -- The complete artifact retains an applicability gap that mechanical agreement between Appendix C and the single-class inventory does not detect. req-mf-001 expressly binds Consumer rejection as well as Producer emission, but is absent from the Consumer enumeration; req-mf-004's Consumer SHOULD is likewise absent. req-sc-007 expressly binds the Producer secret-pattern packing check, and req-cf-002 expressly binds both Consumer and Producer conformance claims, but neither is in the Producer enumeration. Section 4.9 also lists req-ext-002 under Consumer rather than its indexed Producer class. Section 11.1's Appendix-C-wins rule makes a primary-class-only index especially misleading for a class-scoped test suite. These are inherited classification defects, not new local-source or audit behavior.
Recommended fix: In a bounded conformance-index followup, distinguish primary index classification from all roles expressly bound by the requirement body. Add req-mf-001 and the Consumer SHOULD part of req-mf-004 to Consumer enumeration, add req-sc-007 and req-cf-002 to Producer enumeration, and move req-ext-002 to Producer in Section 4.9. Explain in Section 11.1 that primary Appendix C/inventory classification does not exempt a second role explicitly named in a requirement. Preserve the 124 unique IDs and existing requirement bodies; use informative inventory notes for secondary applicability rather than silently changing the preserved requirements-format schema.
[sw-rec-r3-2] openapm-v0.2.md:4032-4056, Citing this specification and Appendix A; prospective #2901 manifest-v0.1.schema.json and lockfile-v0.1.schema.json -- The foundation accurately preserves all four schemas relative to prospective #2901, but the complete candidate changes the manifest alias validator and adds lock-entry alias validation relative to actual main while retaining both existing $id URLs. The citation contract says those URLs are byte-immortal and tells toolchains to pin them verbatim. Consequently, preserving the unpublished prerequisite is not itself evidence that preexisting URL-pinned validators retain identical bytes or acceptance behavior. This is a prerequisite publication/version-identity concern, not a request to restore runtime work to #2820. I verified the candidate-versus-main changes locally; I did not fetch live published schema bytes or establish that a public overwrite has occurred.
Recommended fix: Have the #2901 schema/publication owner reconcile the alias-aware schema revisions with the existing immutable-URL promise before publication: preserve already-published schema bytes at their existing identities, give changed schemas distinct immutable identities, and update the selected revision's citations accordingly. Keep #2820's dependency provenance explicit and do not describe equality to prospective #2901 as equality to the preexisting published baseline. This followup belongs with the prerequisite/publication contract, not the local-source or audit runtime successors.
Nits (2)
[sw-nit-r3-1] openapm-v0.2.md:1615, 1694-1696, 3383-3385 -- The inherited policy text still uses lowercase must in the require-field description and in guidance about enumerating case-distinct spellings. Section 2 explicitly gives lowercase variants no normative weight, leaving the field-reference wording needlessly ambiguous beside req-pl-018.
Recommended fix: De-normativize these descriptive sentences without adding obligations: use 'Exact packages required in the consumer manifest' in the field table and 'need to enumerate' in the two policy-author guidance passages. Leave req-pl-018's operative uppercase requirements unchanged.
[sw-nit-r3-2] openapm-v0.2.md:3210-3212, req-sc-003 -- The inherited phrase 'alias-extended via req-sc-006' links to the HTTP-registry admission rule, not the host-class alias rule. The fragment resolves, but its semantic target is incorrect.
Recommended fix: Replace that req-sc-006 citation with req-sc-005, or cite Section 4.2.3 for the aliases field. Preserve the credential-isolation requirement itself.
Historical regressions in praised strengths
- The historical praise for public-schema byte preservation now needs a narrower baseline: all four schemas match the exact prospective fix(alias): reject path-traversing dependency aliases — fixes #2900 #2901 prerequisite, but the manifest and lockfile schemas differ from actual main at unchanged $id URLs. This is the inherited publication-identity followup sw-rec-r3-2, not a foundation-only schema edit.
Preserved strengths confirmed at d221
- Reviewed the complete 4,412-line v0.2 artifact, retained v0.1 contract differences, both public inventories, all four public schemas, static Astro routes, the historical round-2 record and drafting handoff, and the human-action contract. HEAD is d22119c. Both supplied immutable diffs are byte-identical to git diffs against their stated main and prerequisite bases.
- All four public schemas parse and pass Draft202012Validator.check_schema. All nine $ref occurrences resolve locally. Appendix A contains no inline JSON schema to validate separately. Both requirements manifests validate against the retained informative-format schema.
- Executed the full 16-combination source-key truth table: missing-source objects and multiple source-key combinations are rejected. The known git-plus-path and id-plus-registry false rejections, and unconstrained policy.hash string acceptance, reproduce exactly as Appendix A now discloses. These inherited limitations are not claimed as conformance passes.
- The optional target/targets exclusion correctly accepts neither field, either field alone, and legacy singular null, while rejecting both fields and empty plural lists. Alias probes in Draft 2020-12 validation and ECMAScript confirm valid dotted spellings, trimmed manifest input, canonical lock output, and refusal of reserved dot names, separators, empty strings, NUL, and non-ASCII alias characters.
- The v0.2 body has 124 unique requirement anchors and 124 Appendix C rows: 119 MUST and 5 SHOULD. All ID/keyword/section/primary-class tuples agree with the informative manifest. Section 1.3, Appendix C and the current Appendix D entry agree. All 123 inherited IDs retain their relative anchor order; req-lk-023 is the sole added ID and uses the next free lockfile slot. Inherited req-mf-025 and req-pl-018 are present and indexed.
- Retained v0.1, its inventory, and all four public schemas are byte-identical to d1dd63c. Section 9 is identical between retained v0.1 and v0.2. This proves preservation against the stated prospective prerequisite, not publication or ratification of that prerequisite.
- Source-level fragment checks found no unresolved local links among 795 v0.2 links and 755 retained-v0.1 links, no duplicate explicit anchors, and no mismatched numbered Section-link labels. Static routes keep /spec, /spec/latest and /spec/v0.1 on v0.1, while /spec/v0.2 and /spec/v0.2.0 resolve to the distinct openapm-v020 artifact. No rendered-site build or live-route test was run.
- req-mf-016 continues to separate prefix recognition, source provenance, original declaring anchors, authenticated remote-root/ref containment, selected-local content containment, and destination aliasing. req-lk-023 preserves current-intent precedence, explicit-only saved selection, historical-claim comparison, isolated replay, and refusal before unsupported live native writers. The local-content composition note does not weaken req-sc-015 or archive-link rejection.
- The inactive status, fix(install): preserve local declaring sources and audit current intent read-only #2919 executable-assessment ownership, fix(install): preserve generated aggregate ownership and rebuilds #2923 aggregation ownership, unchanged active v0.1 selection, bare-audit req-lk-017 gap, historical false-orphan replay limitation, Git canonical-byte limitations, and absence of new native-runtime proof remain explicit. These are disclosures, not waivers. This review ran targeted schema and structural probes only, not runtime/conformance campaigns.
- The authentic [BUG] OpenAPM local-path containment contradicts supported trusted-local sibling paths #2818 exception remains limited to its public-comment period; the required two distinct qualified non-author humans, conformance evidence, ratification and migration obligations remain outstanding. Nothing in this advisory review supplies human approval, a publication date, a removal-clock start, or permission to promote latest.
spec-oci-editor -- 7/10, confidence high
The inactive foundation preserves the source/destination, fail-closed extraction and read-only audit boundaries and honestly assigns executable assessment to its successors. A newly reproduced collision in the inherited LF-delimited canonical Git-tree encoding prevents an unqualified ship recommendation and warrants an explicitly scoped next brief, while the attestation trust assumptions merit a small informative clarification. This is an advisory specification review at d22119c, not runtime conformance or human ratification.
Highest-severity findings (1)
[oci-blk-r3-1] docs/src/content/docs/specs/openapm-v0.2.md:1432-1485, Section 5.6.4 / req-lk-015 -- The retained canonical Git-tree encoding is not injective for filesystem names containing LF. It emits mode SP name SP blob-sha256 LF without escaping, length-prefixing, or refusing LF in name. Let H be SHA-256, x be the ASCII bytes 'first payload', and y be 'second payload'. A tree with two mode-100644 files a=x and b=y serializes identically to a tree with one mode-100644 file whose name is 'a ' + H(x) + LF + '100644 b' and whose contents are y. The latter name is 75 ASCII bytes and contains neither slash nor NUL. A memory-only reproduction of the specified construction produced identical canonical bytes and tree_sha256 6a6e33f753153b6880458cc29a85478a2646c7a2954919fbf1c98b4f56ec37e3 for these distinct trees, without finding a SHA-256 collision. Consequently, the documented construction does not supply the claimed collision-resistant tree integrity for this admitted filename domain. This is newly demonstrated inherited specification debt, not a regression introduced by local-source or audit changes; the existing symlink/submodule/filter disclosure does not cover or prevent it. No reference-CLI exploit or runtime conformance result is asserted.
Recommended fix: Escalate this canonical-byte issue for an explicitly authorized follow-up brief rather than silently expanding the bounded corrective amendment. A minimal fail-closed remedy in Section 5.6.4 is to require rejection of a Git tree containing an entry name with U+000A before computing, recording, or accepting tree_sha256, and prohibit silently omitting or renaming that entry. Preserve req-lk-015's existing compute, verify and mismatch-failure MUSTs for admitted entries and preserve old artifacts and schema bytes. Carry the two-tree counterexample into the separately owned conformance work. If all Git filenames must remain supported, specify and version an injective encoding instead; do not silently change the retained digest construction or call an informative limitation a conformance waiver.
Recommended findings (1)
[oci-rec-r3-1] Section 10.12 / Appendix B publisher-attestation reservation; Section 10.4 trust assumptions -- The continued attestation reservation correctly distinguishes declaring-source context from cryptographic provenance and names publisher identity plus package version, but it still does not name the content digest as a future binding target or explain the principled reason verification remains deferred. This matters beside the lockfile-tampering discussion: equality with a recorded digest is integrity relative to that trusted record, not authentication of a record and payload an attacker can replace together. The inactive corrective scope already justifies deferral, so this is a documentation-strengthening recommendation, not a demand to activate signatures.
Recommended fix: Add a short informative paragraph in Section 10.12 stating that current digest checks assume a trusted expected digest or lockfile and do not authenticate simultaneous replacement of both record and payload. Describe the reserved attestation subject as the canonical package/source identity and version, the applicable archive or Git-tree content digest, and publisher identity. Explain that trust-root selection, verification policy and an interoperable envelope require separately scoped design and are outside this local-source/audit correction. Keep attestations and their enforcement inactive, without changing wire fields or weakening any current integrity MUST.
Preserved strengths confirmed at d221
- Reviewed the complete post-merge v0.2.0 artifact, retained v0.1 including all non-shared text, both requirement manifests, all four actual public schemas, Astro routes, and both complete immutable diffs. Both supplied diffs exactly match git diff at d22119c against their stated actual-main and prospective-prerequisite bases; complete added-file hunks match the read artifacts.
- Confirmed d1dd63c is an ancestor of the candidate. The retained v0.1 artifact and manifest and all four public schemas are byte-identical to that prospective prerequisite, not asserted identical to actual main. The foundation-only delta contains only CHANGELOG, Astro configuration, the new specification and its informative inventory.
- The derived projections agree on 124 unique normative requirement IDs, 119 MUST and 5 SHOULD, with req-lk-023 the sole new ID relative to the prerequisite. Both inherited req-mf-025 and req-pl-018 are present. The four public schemas pass Draft 2020-12 metaschema checks and both inventories validate structurally; these are mechanical checks, not Consumer runtime passes.
- Selected local source anchors, local-content containment roots, authenticated remote repository roots and refs, installation scopes, alias destinations, and target deployment roots remain separate authorities. Direct user-relative local sources and unanchored transitive user-relative sources are refused; aliases neither authorize source reads nor turn inventory name into identity or placement.
- Local acquisition must dereference admitted internal links within the selected source root and fail for broken, cyclic or escaping links. The req-lk-023 composition note applies the later req-sc-015 plan to admitted content without allowing that plan to traverse symlinks. The historical unchanged-audit false orphan remains explicitly disclosed, not relabeled an escape or a passing assessment.
- Read-only current-intent replay retains validated manifest, selected saved configuration, then detection precedence; invalid selected inputs do not fall through. It derives expected output independently of ownership, retains prior-target claims for comparison, bounds directory membership, and refuses unavailable recorded native roots. Scratch rebasing, preservation of native databases and sidecars, and unsupported-backend failure before a live writer remain explicit.
- req-lk-017 remains an unqualified stored-hash verification obligation on audit. req-pl-014's ordinary-drift default/advisory scope does not waive independent integrity checks, and req-pl-016 still requires invalid-owner failures in both default and CI modes without deployed-byte mutation. Section 11.2 truthfully distinguishes the bare-CLI gap and unavailable native evidence from those obligations.
- req-lk-013 retains recorded archive-hash verification before any extraction. req-sc-004 still pins application/gzip over tar, rejects zip and other containers, and supplies default 100 MB and 10,000-entry caps. req-sc-002 still rejects traversal, absolute paths, symbolic links and hard links, with fail-closed handling and partial-extraction cleanup. Local-copy semantics do not relax these rules.
- Mirror tolerance remains anchored in recorded resolved_hash rather than resolved_url, including the explicit prohibition on failing solely for a mirror URL mismatch when bytes match. Mirrors replicate original archive bytes rather than rebuilding equivalent content, and req-rg-001 retains immutable published bytes and byte-identical-only republish.
- Lockfile digest positions retain anchored algorithm/length alternatives and explicit bare-hex reader compatibility; writers still owe envelopes. Appendix A openly discloses the inherited policy.hash string-only schema and source-key discriminator gaps without turning structural schema acceptance into semantic validation. The canonical Git symlink, submodule and checkout-filter limitations remain disclosed, although the new encoding collision above needs a distinct response.
- Security threats remain mapped to requirement anchors. req-sc-007 still covers diagnostics, logs, errors, packed bundles, lockfiles and persisted audit records, with default refuse-to-pack secret patterns. Host-class and explicit-port credential isolation, minimum repository cache identity, deny-wins executable authorization, and alias containment without deletion authority are retained.
- The exact v0.2.0 route uses specs/openapm-v020; /spec, /spec/latest and /spec/v0.1 remain on the retained previous minor. v0.2.0 remains an inactive working draft with no assessment selector change or newly activated reserved feature. fix(install): preserve local declaring sources and audit current intent read-only #2919 retains executable assessment ownership and fix(install): preserve generated aggregate ownership and rebuilds #2923 aggregate ownership; this review does not request their runtime work be absorbed into the foundation.
- The prospective fix(alias): reject path-traversing dependency aliases — fixes #2900 #2901 dependency is not represented as ratified. The [BUG] OpenAPM local-path containment contradicts supported trusted-local sibling paths #2818 exception remains limited to that amendment's public-comment period; two distinct qualified non-author human reviews, conformance evidence, ratification and any migration announcement remain separate obligations. No human approval, publication date, latest promotion or new runtime success is inferred.
- This execution performed read-only artifact inspection, structural checks and one memory-only canonical-encoding counterexample. It did not run pytest, install/audit, a native host, a cross-platform campaign or a rendered-site build, and does not adopt historical test counts as results at this SHA.
spec-pkgmgr-editor -- 7/10, confidence high
The inactive local-source and current-intent audit foundation preserves the earlier corrective work and closes the historical package-manager followups at d22119c. One prerequisite-origin issue remains: #2901 changes two schema contracts at URLs the specification promises are byte-immutable, so this integrated candidate needs a corrected prerequisite and another brief rather than an unqualified preservation claim. This is advisory source and structural review, not executable conformance, publication authorization, or human ratification.
Highest-severity findings (1)
[pkg-blk-r3-1] Citing this specification, openapm-v0.2.md:4032-4042; Appendix A:4077-4086; inherited docs/public/specs/schemas/manifest-v0.1.schema.json and lockfile-v0.1.schema.json; candidate-full-main.diff -- The complete candidate inherits a schema-identity break from prospective #2901 even though its foundation-only delta preserves that prerequisite exactly. Against actual main e38261c, both public v0.1 manifest and lockfile schemas change bytes and alias validation while retaining their existing filenames and identical $id URLs. The retained specification and this draft both promise that schemas are byte-immortal at those URLs; Appendix A additionally says schema repairs require separately versioned artifacts. A bounded Draft 2020-12 check confirms that a minimal manifest with dependencies.apm=[{git: acme/pkg, alias: '.'}] and a minimal lock with dependencies=[{repo_url: acme/pkg, alias: '.'}] each pass the main schema and fail the candidate schema under the same respective $id. These are schema-boundary counterexamples, not claims that unsafe aliases should conform to the new prose. Comparing only against the unratified prerequisite hides the published-identity violation: cached and freshly fetched schema pins can denote different contracts. This invalidates the stated immutable-schema guarantee and requires reconciliation before the integrated candidate is presented as preserving old schema identities.
Recommended fix: Assign the correction to the #2901 prerequisite owner rather than reabsorbing runtime work into #2820. Preserve the existing public v0.1 schema bytes and URLs from actual main; place alias-constrained schema revisions under distinct versioned filenames and $id values, with explicit references and migration guidance in the amendment. Alternatively, retain the old structural schemas and document that the new alias checks are prose-level consumer obligations, without claiming those preserved schemas enforce them. Then reanchor the inactive foundation to the corrected prerequisite and update its inheritance and Appendix A descriptions. Do not weaken alias refusal, rewrite the old immutable guarantee, remove old routes, or infer human approval from this engineering change.
Historical regressions in praised strengths
- The earlier preservation strength no longer holds relative to actual main for the two alias-bearing public schemas. They are unchanged only relative to prospective fix(alias): reject path-traversing dependency aliases — fixes #2900 #2901. The policy and requirements-format schemas still match actual main. This is the single prerequisite-origin regression reported as pkg-blk-r3-1, not a claim that docs(spec): retain the inactive OpenAPM v0.2 foundation #2820 independently edited those schemas.
Preserved strengths confirmed at d221
- Reviewed the complete post-merge v0.2.0 artifact, all differing retained-v0.1 text, both requirement inventories, all four public schemas, and the routes. Both supplied immutable diffs exactly match git diff at the stated main/prerequisite and candidate SHAs; their complete added specification and inventory bodies equal the artifacts read. The foundation-only delta is four files and 4,965 added lines, with no runtime or assessment-selector change.
- Req-mf-016 separates path syntax from source authorization, original declaring-source anchors from installation scope, and remote repository containment from operator-local admission. Remote provenance takes precedence over local admission; _local/ spelling and recorded path strings cannot establish local trust. Direct user-relative and unanchored transitive user-relative reads remain refused.
- Req-mf-016(d) defines admitted internal local-link dereferencing separately from req-sc-015's post-acquisition source plan and archive-link rejection. The local-content composition note correctly prevents a dereferenced regular resource from becoming obsolete solely because its original representation was a link, without claiming race-free isolation or whole-install atomicity.
- Inherited req-mf-025 preserves canonical trimmed alias placement through lock emission, reconstruction, replay, and removal without changing source identity, revision, or local-source anchors. It rejects reserved names and destinations resolving to or outside apm_modules, preserves valid dotted spellings, forbids inventory-name fallback, and distinguishes unknown-field preservation from optional alias lifecycle support.
- Req-lk-023 derives expected output from sources and current target intent, with validated manifest selection preceding selected saved configuration and detection. Historical claims widen installed-file comparison only; they cannot restore an unsaved override or suppress missing expected files. Directory descendants, file-shaped claims, unavailable historical native roots, scratch rebasing, and unsupported native-writer refusal are addressed explicitly.
- The audit contract preserves live manifest, lockfile, configuration, deployment, native database, and sidecar bytes. Failed target resolution or replay remains a failed check even when default mode reports it advisory. Req-pl-014 does not erase CI/conformance failures, and req-lk-003, req-lk-017, and req-pl-016 retain their independent integrity obligations.
- The corrective delta preserves the inherited node-semver reference, precedence and prerelease rules, build-metadata tie break, intersection-pick default, empty-intersection refusal, lockfile-version monotonicity and adjacent-version tolerance, explicit hash-envelope writers, bare-hex reader tolerance, and opt-in frozen behavior. It does not activate nesting, workspaces, attestations, withdrawal, range widening, or normative registry HTTP. Archive reproducibility and portable local content hashing remain explicitly outside the present deterministic contract.
- Mirror retrieval remains anchored to the recorded archive digest, not its URL or reconstructed source bytes; Registry req-rg-001 still requires immutable version bytes and idempotent republishing. Producer, Consumer, Registry, and Governance remain separately enumerated, with req-lk-023 and inherited req-mf-025 in the Consumer enumeration and req-pl-018 in Governance.
- Read-only checks found 124 unique v0.2 anchors, 119 MUST and 5 SHOULD index rows, and a matching inventory; the retained prerequisite has 123. Req-lk-023 is the sole added ID and inherited anchor order is preserved. All four schemas pass Draft 2020-12 metaschema validation, and both inventories validate against the retained informative format. These are structural checks, not runtime-conformance results.
- Status, Section 11.2, Section 12.6, and Appendix D distinguish inactive preparation from executable assessment, publication, and ratification. The historical bare-audit stored-hash gap, internal-resource-link false-orphan result, Git canonical-byte limits, schema limitations, and lack of native round-trip evidence remain disclosures rather than waivers. No runtime suite, rendered-site build, or hosted-runtime campaign was executed in this review.
- Section 9 retains the qualified non-author review requirement and the previous-minor announcement-to-removal window. The supplied human-actions record correctly requires two distinct eligible humans, limits the [BUG] OpenAPM local-path containment contradicts supported trusted-local sibling paths #2818 exception to that amendment's public-comment period, grants no such exception to fix(alias): reject path-traversing dependency aliases — fixes #2900 #2901, and starts no removal clock merely from draft preparation. No old route is removed or latest alias promoted.
spec-tag-architect -- 8/10, confidence high
Actual round-3 review finds the inactive corrective foundation architecturally strong and the historical TAG followups closed at d22119c. One prerequisite-origin issue remains: changed schemas would overwrite publicly served byte-immortal $id resources, requiring an explicit publication-identity correction before this candidate can uphold its pinning claim. This advisory establishes source, schema, inventory, and public-schema-byte observations only, not runtime conformance, a rendered-site build, qualifying human approval, or ratification.
Highest-severity findings (1)
[tag-blk-r3-1] Citing this specification, openapm-v0.2.md:4032-4036; Appendix A:4044-4056, 4084-4086; docs/public/specs/schemas/manifest-v0.1.schema.json:108-112 and lockfile-v0.1.schema.json:39-44; inherited prerequisite #2901 -- The combined candidate would replace two already-public schema resources at unchanged $id URLs despite the specification's explicit byte-immortality guarantee. The foundation correctly preserves prospective #2901 byte-for-byte, but that prerequisite changes manifest-v0.1.schema.json and lockfile-v0.1.schema.json relative to actual main e38261c. Independent HTTP GETs during this review returned 200 and bytes exactly matching actual main, not the candidate: the live manifest SHA-256 is 7bdefbe443d3315d71add021c777d776c9cfd4942acb19750a799f46fa0d1344 versus candidate fe889eb93779a889a1656cc58152cc53651dd79e65fcbb6bae5530f18afc8377; the live lockfile SHA-256 is 6c0dca9e7994035b55da17340b1f9f6c6673501c63ebd947400cf472d5723560 versus candidate 3c80dd8da7a242b5b5407d7a8633e2e28f1b0d61aa843577247fcf55b52502a5. This is not cosmetic: otherwise structurally valid manifest and lockfile samples with alias '..' validate against the public schemas and fail against the candidate schemas. Consequently, two tools pinning the same advertised immutable $id can obtain different validators depending on cache age. Prospective ancestry and inactive v0.2 status do not reconcile that published resource-identity guarantee; this is a prerequisite-origin contract defect, not an assertion that #2820 itself introduced the schema edits.
Recommended fix: Resolve the schema publication boundary with the #2901 owner: retain the currently served bytes at both existing $id URLs, place any alias-aware replacement schemas under distinct versioned filenames and $ids, and update the relevant specification and validation references to identify the selected schema revision explicitly. Then reanchor the inactive #2820 foundation and its preservation statements to the corrected prerequisite. Keep unsafe-alias refusal in the normative prose; do not weaken it to match an old schema. Do not import #2919 or #2923 runtime work into this foundation, claim that the old URLs were unpublished, or treat human approval as an implicit waiver of byte immutability.
Historical regressions in praised strengths
- The earlier TAG review praised preservation of existing public schema bytes and identities. At this candidate, preservation remains true relative to prospective fix(alias): reject path-traversing dependency aliases — fixes #2900 #2901, but not relative to actual main or the currently served public resources: two schema bodies change under the same $ids. See tag-blk-r3-1; the distinction must survive synthesis rather than being hidden by the prerequisite-relative diff.
Preserved strengths confirmed at d221
- Reviewed immutable d22119c. Both supplied complete diffs exactly match git diff against their declared bases. The new-file additions exactly match the complete post-merge v0.2 specification and inventory; retained v0.1, both inventories, all four schemas, routes, and all remaining full-main diff blocks were read. The foundation-only delta contains precisely CHANGELOG, Astro configuration, the new specification, and its inventory.
- Independent source checks confirm 124 unique v0.2 requirement anchors, 119 MUST and 5 SHOULD, with exact ID/keyword/section/class agreement between Appendix C and the informative inventory. All 123 inherited anchors retain their order; req-lk-023 is the sole new ID relative to the prerequisite. Retained v0.1 has 123 requirements, 118 MUST and 5 SHOULD. Both inventories validate against the retained requirements-format schema, and all four schemas pass Draft 2020-12 metaschema validation.
- The machine-readable inventory declares spec_version v0.2.0 separately from requirements_format_version 1. Section 12.3 designates source-level requirement anchors as the canonical extraction target, with the table and manifest derived from them; no rendered-HTML scraping is necessary. Section 12.6 explicitly leaves the normative manifest format reserved and the assessment selector on v0.1.
- The exact /spec/v0.2.0 route targets the explicit specs/openapm-v020 slug, with a distinct-artifact requirement for a later patch. /spec, /spec/latest, and /spec/v0.1 retain their actual-main destinations. The sidebar labels v0.2.0 as a draft. Source-level checking found no unresolved local fragments among 795 references; no rendered-site build or future route availability is claimed.
- Status, Section 11.2, Appendix D, and the inventory distinguish inactive foundation preparation from coupled executable assessment in fix(install): preserve local declaring sources and audit current intent read-only #2919 and aggregation in fix(install): preserve generated aggregate ownership and rebuilds #2923. They identify fix(alias): reject path-traversing dependency aliases — fixes #2900 #2901 by exact prospective SHA rather than as ratified ancestry. No v0.2 runtime assessment, publication date, announcement date, ratification, or latest promotion is inferred.
- Section 9 is byte-identical between the retained and corrective specifications. Two qualified non-author human reviewers remain required, the authentic [BUG] OpenAPM local-path containment contradicts supported trusted-local sibling paths #2818 exception concerns only that amendment's public-comment period, and the previous minor remains supported without a removal date. This AI review supplies neither human approval nor an exception for fix(alias): reject path-traversing dependency aliases — fixes #2900 #2901.
- Source anchoring, source containment, installation scope, repository identity, and alias placement remain distinct. req-mf-016 rejects unknown local provenance, remote-to-local reinterpretation, unanchored user-relative reads, and remote repository escapes. Its local-link admission rule is explicitly separate from target source-plan exclusions; source selection does not promise harmless contents, race-free isolation, or whole-install atomicity.
- req-lk-023 derives expected output from resolved source content and current intent, not ownership records. Historical directory claims widen comparison only; saved explicit-only selection does not invent detection predicates. Live configuration, deployments, native databases, and sidecars remain read-only, with unsupported native replay failing before its live writer.
- req-mf-025, req-lk-017, req-pl-016, and req-sc-015 retain their inherited requirement bodies. The bare-audit stored-hash gap, historical internal-resource-link false-orphan result, Git-tree ambiguities, schema discriminator/hash limits, and missing native round-trip evidence remain disclosed without becoming normative waivers. Static bindings and schema checks are not represented as runtime passes.
- Existing x-* recognition, round-trip preservation, and future normative-key collision protections remain intact. No new telemetry, persistent cross-organization identifier, publisher-identity guarantee, marketplace-output format, or reserved workspace/registry-wire feature is activated. generated_at remains opt-in for new lockfiles, and req-cf-002 retains MUST-for-claim test-invocation and fixture disclosure for Consumer and Producer claims.
This panel is advisory, not a human approval or normative acceptance. This in-place update supersedes older candidate guidance on this same surface; the previous body and all unmodified review JSON are retained in the session evidence archive.
Skip audit's opportunistic update check and opt cold replay into noncreating transport-config reads without changing install defaults or transport precedence. Add warm/cold installed-CLI and historical-native refusal controls, and preserve the symlink-root refusal's structured result. Normalize only the repository lock's two machine-local native URI claims and matching ledger rows; no live native state is removed, reconciled, or declared absent. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keep real update-notice stderr assertions for eligible policy commands while asserting that read-only audit never invokes the update helper. Exercise both JSON flag spellings and remove inherited E2E suppression in this focused control. Production source remains identical to 300a24a. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Preserve confirmed aggregate removal and survivor identity through canonical owners; make refusal recovery sufficient and scoped, bound attachment and audit comparison work, and keep Windows audit configuration reads noncreating. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…-production-shepherd
…y order Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Aliases were only matched against a lax character regex, letting values like "..", "./x", or "foo/../bar" escape apm_modules at download and integrate time. Now validating every parsed alias through path_security's segment checks and guarding the resolved install path inside the download/integrate phases. Adds unit coverage for traversal and safe aliases.
Wrap validate_path_segments in parse_alias_override so '.'/'..' aliases translate PathTraversalError into the existing allowed-character message instead of leaking a low-level technical error. Strengthen traversal tests to assert the friendly message.
A valid alias like 'safe-name' passes parse-time validation, but apm_modules_dir/safe-name can itself be a symlink pointing outside apm_modules_dir. ensure_path_within is the only guard that resolves symlinks before containment (download.py:65, integrate.py:622); this test proves the escape raises PathTraversalError and never writes outside the managed tree.
The parser rejects traversal aliases (parse_alias_override), and the
ensure_path_within containment guards exist at download.py:65 and
integrate.py:622 as the defense-in-depth last line. But no test drove
those
guards through the real phase entry points -- the PR "Scenario 4" claim
(install path can never escape apm_modules even if the parser is
bypassed)
was proven only at unit tier.
Add install-tier regression traps that route malicious aliases through
the
actual phase run() functions:
- tests/red_team/install/test_alias_path_escape.py
* download.run() rejects a '..' traversal alias and a symlink that
resolves outside apm_modules_dir via PathTraversalError, asserting
no
download bytes land.
* integrate.run() rejects the same two vectors before materialization.
* Safe-alias controls confirm no false positive.
- tests/unit/test_registry_entry_alias_traversal.py
* Covers the secondary parse_registry_object_entry alias validation
(registry_entry.py:86): regex layer (%2e%2e) and
validate_path_segments
layer ('..', 'pkg/..'), plus a safe-alias affirmative control.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Address the PR #2901 panel and Copilot follow-ups: route all alias ingress and materialization through existing owners, reject root-equal destinations, preserve local sibling sources, and defend real reinstall metadata and hashes with regression and architecture tests. Include actionable diagnostics and migration guidance. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Preserve e845ebf and its explicit non-None contract through the phase-level RuntimeError guard. The shared materialization owner replaces the parallel alias join. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Address round-two architecture/security and lifecycle findings. Compare both roots through path_security, give safe alias recovery guidance, and preserve existing legacy-plugin validation before alias-aware resolution can normalize cached files. Main passes the legacy missing-metadata cases; added preflight keeps that behavior. Windows prefix and legacy-preflight mutation controls fail with guards removed. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keep authenticated remote coordinates separate from flat aliases. Inject the existing read-only legacy cache admission at actual reuse after canonical fetch decisions, not preparation; retain same-ref failure and transactional replacement. Extend real resolver and CLI lifecycle contracts with aliased remote siblings and invalid-cache ref changes. Mutation controls detect both source-anchor regression and misplaced or missing admission. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Retain main req-pl-018 and Section 9.2, reconcile the 123-requirement inventory, and make human ratification and publication limits explicit. Preserve all original runtime pending linked successors. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Continue the existing PR #2901 CI recovery without resetting its run. Preserve the recovered implementation and review folds: durable alias projection, contained alias scanning, specification conformance, and current-remote ref observations after successful checkout. Original contributor and follow-up commits remain in the lineage. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The mutation gate showed the previous fixture passed even when receipt handling was removed because no bare-cache directory existed. Materialize the canonical shard directory so the stale-ref fallback is reachable and the regression fails without the receipt guard. Production code is unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Continue CI recovery2 after Linux shard2 exposed four generic Mock dependency references whose undeclared alias attribute became another Mock. Model the real unaliased DependencyReference default explicitly instead of weakening production alias validation. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Preserve the original #2820 history while moving executable ownership to the published #2919 and #2923 successors. Restore current main runtime and the active v0.1 assessment verbatim; retain the exact corrective draft overlay and its release-note obligation. Final normative repin still follows qualified-human #2901 landing. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Preserve Danvs60's alias traversal repair and the recovered alias/cache contracts while integrating upstream main. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…endment Carry the full 124-requirement union without activating v0.2 or replacing human Section 9.3 review. Preserve exact prospective v0.1 schemas and all local/audit boundaries, with assessment owned by #2919. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keep existing public v0.1 schemas byte-identical and select independent v0.1.41 schemas for alias validation. Accept the new exact manifest ID through the existing contract owner while retaining old-ID compatibility and fail-closed unknowns. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
docs(spec): retain the inactive OpenAPM v0.2 foundation
TL;DR
Narrow the original monolithic proposal to the inactive OpenAPM v0.2.0 specification foundation. Preserve its complete source lineage while #2919 owns local-source/audit implementation and executable assessment and #2923 owns aggregate repair. This candidate inherits exact #2901
5a0d872b9dd63b78b08923eddfad0ed1f9b369b4prospectively; that prerequisite is pushed, not ratified or landed.Important
Draft, not ready for normative acceptance. The guardian's inherited LF-filename canonical-tree encoding finding remains unresolved. Two eligible non-author human reviews, the prerequisite amendment process, and coupled #2919 evidence remain outstanding. Nothing activates v0.2, advances
latest, grants a waiver, or claims #2815's runtime fix here.Problem (WHY)
$idURLs. Exact fix(alias): reject path-traversing dependency aliases — fixes #2900 #29015a0d872...restores the original bytes and adds independentmanifest-v0.1.41andlockfile-v0.1.41resources.req-lk-015debt is disclosed, not repaired or waived.The split makes the written contract and executable claims independently reviewable. The Agent Skills guidance is explicit: "do the work, run a validator (a script, a reference checklist, or a self-check), fix any issues, and repeat until validation passes." Here structural, active-version, successor-runtime, and human-process evidence remain separate; one does not substitute for another.
Approach (WHAT)
Implementation (HOW)
Final source candidate:
9e5a0ebf6ea595be4de480402c6c4e15b95751b6. Relative to exact #2901, this PR owns only:docs/src/content/docs/specs/openapm-v0.2.mddocs/public/specs/manifests/openapm-v0.2.requirements.ymldocs/astro.config.mjs/spec/v0.2.0route and draft sidebar entry;/spec,/spec/latest,/spec/v0.1still select v0.1.CHANGELOG.mdCompared with the 123-requirement prerequisite, only
req-lk-023is added. Inheritedreq-mf-025andreq-pl-018remain intact. Primary inventory classification is not an exemption from an existing secondary-role clause. The old v0.1 specification and inventory match the exact amended prerequisite; the four old schemas retain actual-maine38261c...bytes and identities.Diagrams
The exact prospective prerequisite feeds the foundation; executable local/audit and aggregate work remain separately owned.
flowchart LR Alias["PR 2901: alias prerequisite"] Foundation["PR 2820: inactive v0.2 foundation"] Local["PR 2919: local and audit assessment"] Aggregate["PR 2923: aggregate repair"] Human["Section 9.3 human amendment decisions"] Alias -->|"exact prospective ancestry"| Foundation Foundation -->|"exact draft and inventory"| Local Aggregate -->|"separately owned integration"| Local Human -.->|"required before activation"| Foundation classDef changed stroke-dasharray: 5 5; class Foundation changed;Trade-offs
Benefits
Validation
Exact-head local evidence at
9e5a0eb...:All seven canonical lint categories and the architecture-boundary script passed after actual-main integration. Strict
owner_touch_gatev2 evidence covers all four owners in the full-main delta, with exact-head passing functional cases and 24 registered mutation cases. The narrower four-document delta's zero-owner report is not an exemption.The two existing skips belong to the active v0.1 suite, not a new v0.2 waiver. Guardian mechanics check all six schema metaschemas, old-byte preservation, new
$ids, 124/119/5 counts, source links, retained routes and inactive scope. This is not the complete #2919 runtime assessment or human ratification. Hosted CI is being observed separately; no earlier candidate execution is relabeled as this head.Scenario Evidence
test_alias_survives_lock_replay_without_changing_source[git-.safe]test_only_actual_current_remote_resolution_can_publish_named_observationtest_git_semver_eligibility_is_source_awaretest_manifest_schema_negotiates_normative_v01_registry_shapeRequired human actions
Section 9.3 requires an amendment issue labeled
spec/openapm-vN.x, an editor-draft PR, and two distinct non-author human reviewers: one with implementation experience, one with consumer/integrator experience. It names no particular person, job title, magic wording or ratification button. An auditable human PR review should identify the exact SHA, experience role, requirements/evidence examined, and the person's decision. Bots, two AI personas, or the author's own comment cannot fill those seats.Suggested human wording, only when true:
For #2901, the 14-day public-comment period follows the completed eligible pair of approvals. Publish notice linking both reviews and the exact revision; use the real notice timestamp if later than the second approval. No first-draft, AI-review or CI date starts this clock. No applicable exception has been established for #2901.
For #2820/#2818, the recorded one-amendment exception omits only this corrective amendment's 14-day public-comment period. It does not waive the two qualified reviews, coupled conformance evidence, ratification, or migration obligations. Apply the v0.2 lineage label to #2818 and review the final foundation with exact #2919 evidence. There is no #2820 countdown to backdate under that exception.
The maintainer's eventual acceptance record should link the two human reviews, exact #2820/#2919 evidence, the #2818 exception and actual #2901 status, and specify whether it authorizes inactive landing or another precise publication action. No such decision is claimed here. The inherited LF-encoding remedy needs its own authorized normative brief. #2897 remains ordinary code review, not an automatic Section 9.3 amendment.
How to test
5a0d872...: only the four foundation paths above should differ.uv run --extra dev pytest -q tests/spec_conformance: active-version evidence should pass with its existing two skips.npm --prefix docs ci && npm --prefix docs run build: schemas and old/new routes should render without broken relative links.Co-authored-by: Copilot App 223556219+Copilot@users.noreply.github.com