S00-011: Verify public npm access and exact-version tarball integrity
Changes: Add a scoped fresh-cache registry probe, safe reproduction instructions and artifact ignore rule; record actual TLS-enabled metadata/download results and review handoff without selecting a stack or changing the harness. Validation: Original npm view command and verify.py returned exit 0; react@19.3.1 tarball (26394 bytes) matched registry SHA-512. make check passed validation and 66 tooling tests. git diff --check passed. App install/build and different-harness connectivity remain unverified. Task: S00-011 Agent: auto-ci-cd-d105e8027730 Role: ci-cd Action: claim Status: review Task title: Restore verified npm registry access for the stack spike
This commit is contained in:
1 parent
b8afc70e5f
commit
e4672fba91
10 files changed
+264
-8
No files matched your search
@@ -0,0 +1 @@
|
||||
artifacts/
|
||||
@@ -0,0 +1,79 @@
|
||||
# Verified public npm registry path — S00-011
|
||||
|
||||
Input: S00-002 failed to resolve registry.npmjs.org. Output: a repeatable public
|
||||
metadata and exact-version tarball probe in the current executor harness.
|
||||
This is connectivity evidence, not a framework choice or an application build.
|
||||
|
||||
## Execution environment and reproduction
|
||||
|
||||
Verified in the fresh auto-ci-cd-d105e8027730 executor on 2026-10-15:
|
||||
Node v26.3.0, npm 11.16.0, Python 3, macOS paths. These are observed tools,
|
||||
not accepted project runtime versions. The supplied harness has network access
|
||||
enabled, workspace-write sandboxing and approval policy never. No harness,
|
||||
runner, DNS, proxy, certificate or Git configuration was changed by this task.
|
||||
The initial working tree contained only the coordinator's state/tasks.json claim.
|
||||
|
||||
The next fresh executor must retain network-enabled execution, working DNS and
|
||||
HTTPS egress to registry.npmjs.org:443, normal certificate trust, and project-only
|
||||
source writes with temporary writes under /private/tmp. No credentials are needed.
|
||||
Do not disable TLS or relax the write sandbox. The previous DNS failure was not
|
||||
reproduced here; its external correction mechanism is unknown. This report does
|
||||
not promise network availability in a different or future harness.
|
||||
|
||||
From the project root:
|
||||
|
||||
```sh
|
||||
npm view react version license engines --json --cache /private/tmp/luma-stack-npm-cache --fetch-retries=0 --fetch-timeout=15000
|
||||
python3 experiments/0001-stack/registry-access/verify.py
|
||||
```
|
||||
|
||||
The first command exactly repeats the original failure. It returned exit 0:
|
||||
|
||||
```json
|
||||
{"version":"19.3.1","license":"MIT","engines":{"node":">=0.10.0"}}
|
||||
```
|
||||
|
||||
`npm config get strict-ssl` returned `true` (exit 0). The second command uses a
|
||||
new TemporaryDirectory under /private/tmp with empty user/global npmrc files
|
||||
and a fresh cache, runs from there to avoid project npmrc, and removes that
|
||||
temporary directory after execution. It refuses NODE_TLS_REJECT_UNAUTHORIZED=0.
|
||||
It invokes these argument arrays via subprocess, without a shell:
|
||||
|
||||
```text
|
||||
npm view react@19.3.1 version license engines dist --json <common-options>
|
||||
npm pack react@19.3.1 --ignore-scripts --json --pack-destination=<absolute-scope>/artifacts <common-options>
|
||||
```
|
||||
|
||||
The exact common options are:
|
||||
|
||||
```text
|
||||
--registry=https://registry.npmjs.org/ --strict-ssl=true
|
||||
--fetch-retries=0 --fetch-timeout=15000
|
||||
--cache=<fresh-temp>/cache --userconfig=<fresh-temp>/user.npmrc
|
||||
--globalconfig=<fresh-temp>/global.npmrc
|
||||
```
|
||||
|
||||
The probe installs no dependencies, extracts no archive, runs no package scripts
|
||||
and adds no package manifest/lockfile. React is only a public connectivity sample.
|
||||
It checks the metadata version and exact HTTPS tarball URL, downloads through
|
||||
npm, and independently compares Python hashlib SHA-512/base64 with dist.integrity
|
||||
and npm pack's integrity. It uses standard libraries, not custom cryptography.
|
||||
Errors/mismatches exit nonzero. Do not print private environment/configuration.
|
||||
|
||||
## Actual result
|
||||
|
||||
Both child npm commands and verify.py returned exit 0, using the fresh cache:
|
||||
|
||||
- Package: react@19.3.1; metadata license MIT.
|
||||
- URL: https://registry.npmjs.org/react/-/react-19.3.1.tgz
|
||||
- Retrieved size: 26394 bytes.
|
||||
- Registry and independently computed integrity:
|
||||
`sha512-QNhWdt7nrgVWWQG58QuGsAR3jv3Hbe4mb4vz7w2csnHavciZJgda1CPNaldF6eVxv90ud3jUXpKlHL69gO38yw==`
|
||||
|
||||
The local `artifacts/` directory contains the tarball, public metadata.json and
|
||||
result.json; it is deliberately ignored by Git. Rerun the probe for independent
|
||||
review instead of trusting an archived result. No secrets are recorded. Registry
|
||||
signature/provenance verification is not claimed; the acceptance check is registry
|
||||
integrity over verified HTTPS. Browser/CORS, dependency install, build, framework
|
||||
compatibility and license acceptance remain outside this task. S00-002 must run
|
||||
its own clean install/build and make its own stack/runtime decision after review.
|
||||
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Fetch public npm metadata/tarball without installing or running package code."""
|
||||
import base64
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parent
|
||||
PACKAGE = "react@19.3.1" # Connectivity sample only; not a stack decision.
|
||||
|
||||
|
||||
def main():
|
||||
if os.environ.get("NODE_TLS_REJECT_UNAUTHORIZED") == "0":
|
||||
raise SystemExit("Refusing disabled Node TLS verification")
|
||||
artifacts = ROOT / "artifacts"
|
||||
artifacts.mkdir(exist_ok=True)
|
||||
# Empty configuration files prevent inherited npm credentials/config from
|
||||
# being needed for this public probe. Never print the process environment.
|
||||
with tempfile.TemporaryDirectory(prefix="luma-registry-", dir="/private/tmp") as temp:
|
||||
temp = Path(temp)
|
||||
for name in ("user.npmrc", "global.npmrc"):
|
||||
(temp / name).write_text("", encoding="utf-8")
|
||||
common = [
|
||||
"--registry=https://registry.npmjs.org/", "--strict-ssl=true",
|
||||
"--fetch-retries=0", "--fetch-timeout=15000",
|
||||
f"--cache={temp / 'cache'}", f"--userconfig={temp / 'user.npmrc'}",
|
||||
f"--globalconfig={temp / 'global.npmrc'}",
|
||||
]
|
||||
|
||||
def npm(args):
|
||||
# Run outside the project so no project .npmrc is inherited.
|
||||
result = subprocess.run(["npm", *args, *common], cwd=temp,
|
||||
check=True, capture_output=True, text=True,
|
||||
timeout=60)
|
||||
print("npm " + " ".join(args) + " [isolated TLS/cache options]: exit 0")
|
||||
return json.loads(result.stdout)
|
||||
|
||||
metadata = npm(["view", PACKAGE, "version", "license", "engines", "dist", "--json"])
|
||||
if metadata["version"] != "19.3.1":
|
||||
raise SystemExit("Unexpected package version")
|
||||
if metadata["dist"]["tarball"] != "https://registry.npmjs.org/react/-/react-19.3.1.tgz":
|
||||
raise SystemExit("Unexpected tarball origin/path")
|
||||
integrity = metadata["dist"]["integrity"]
|
||||
algorithm, expected = integrity.split("-", 1)
|
||||
if algorithm != "sha512":
|
||||
raise SystemExit("Expected SHA-512 registry integrity")
|
||||
base64.b64decode(expected, validate=True)
|
||||
packed = npm(["pack", PACKAGE, "--ignore-scripts", "--json",
|
||||
f"--pack-destination={artifacts}"])
|
||||
if len(packed) != 1 or packed[0]["filename"] != "react-19.3.1.tgz":
|
||||
raise SystemExit("Unexpected pack output")
|
||||
tarball = artifacts / "react-19.3.1.tgz"
|
||||
actual = "sha512-" + base64.b64encode(hashlib.sha512(tarball.read_bytes()).digest()).decode("ascii")
|
||||
if actual != integrity or packed[0]["integrity"] != integrity:
|
||||
raise SystemExit("Tarball integrity mismatch")
|
||||
(artifacts / "metadata.json").write_text(json.dumps(metadata, indent=2) + "\n", encoding="utf-8")
|
||||
result = {"package": PACKAGE, "bytes": tarball.stat().st_size,
|
||||
"integrity": actual, "registry_integrity_match": True}
|
||||
print(json.dumps(result, indent=2))
|
||||
(artifacts / "result.json").write_text(json.dumps(result, indent=2) + "\n", encoding="utf-8")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,6 +1,6 @@
|
||||
# Матрица задач
|
||||
|
||||
Generated; state revision **6**. Canonical status: state/tasks.json.
|
||||
Generated; state revision **8**. Canonical status: state/tasks.json.
|
||||
|
||||
| ID | Этап | Оператор | Reviewer | Статус | Owner | Зависимости | Задача |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
@@ -13,7 +13,7 @@ Generated; state revision **6**. Canonical status: state/tasks.json.
|
||||
| [S00-007](tasks/S00-007.md) | S00 | security | orchestrator | todo | | S00-004, S00-005 | Утвердить password и crypto unlock модель |
|
||||
| [S00-008](tasks/S00-008.md) | S00 | ci-cd | qa | todo | | S00-003, S00-004 | Описать WSS/upload/TURN/push topology |
|
||||
| [S00-009](tasks/S00-009.md) | S00 | orchestrator | security | todo | | S00-003, S00-004, S00-005, S00-006, S00-007, S00-008 | Согласовать результаты spikes |
|
||||
| [S00-011](tasks/S00-011.md) | S00 | ci-cd | security | todo | | S00-001 | Restore verified npm registry access for the stack spike |
|
||||
| [S00-011](tasks/S00-011.md) | S00 | ci-cd | security | review | auto-ci-cd-d105e8027730 | S00-001 | Restore verified npm registry access for the stack spike |
|
||||
| [S00-010](tasks/S00-010.md) | S00 | qa | orchestrator | todo | | S00-001, S00-002, S00-003, S00-004, S00-005, S00-006, S00-007, S00-008, S00-009 | Gate: Профиль и проверка стека |
|
||||
| [S01-001](tasks/S01-001.md) | S01 | orchestrator | security | todo | | S00-010 | Описать identity/model contracts |
|
||||
| [S01-002](tasks/S01-002.md) | S01 | orchestrator | security | todo | | S00-010, S01-001 | Описать async account context |
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
- [S00-007](../tasks/S00-007.md): Утвердить password и crypto unlock модель — security; todo.
|
||||
- [S00-008](../tasks/S00-008.md): Описать WSS/upload/TURN/push topology — ci-cd; todo.
|
||||
- [S00-009](../tasks/S00-009.md): Согласовать результаты spikes — orchestrator; todo.
|
||||
- [S00-011](../tasks/S00-011.md): Restore verified npm registry access for the stack spike — ci-cd; todo.
|
||||
- [S00-011](../tasks/S00-011.md): Restore verified npm registry access for the stack spike — ci-cd; review.
|
||||
- [S00-010](../tasks/S00-010.md): Gate: Профиль и проверка стека — qa; todo.
|
||||
|
||||
## Граница этапа
|
||||
|
||||
@@ -8,7 +8,7 @@ S00-006,S00,orchestrator,security,todo,,S00-002,Зафиксировать brows
|
||||
S00-007,S00,security,orchestrator,todo,,"S00-004, S00-005",Утвердить password и crypto unlock модель
|
||||
S00-008,S00,ci-cd,qa,todo,,"S00-003, S00-004",Описать WSS/upload/TURN/push topology
|
||||
S00-009,S00,orchestrator,security,todo,,"S00-003, S00-004, S00-005, S00-006, S00-007, S00-008",Согласовать результаты spikes
|
||||
S00-011,S00,ci-cd,security,todo,,S00-001,Restore verified npm registry access for the stack spike
|
||||
S00-011,S00,ci-cd,security,review,auto-ci-cd-d105e8027730,S00-001,Restore verified npm registry access for the stack spike
|
||||
S00-010,S00,qa,orchestrator,todo,,"S00-001, S00-002, S00-003, S00-004, S00-005, S00-006, S00-007, S00-008, S00-009",Gate: Профиль и проверка стека
|
||||
S01-001,S01,orchestrator,security,todo,,S00-010,Описать identity/model contracts
|
||||
S01-002,S01,orchestrator,security,todo,,"S00-010, S01-001",Описать async account context
|
||||
|
||||
|
@@ -0,0 +1,4 @@
|
||||
Verify public npm access and exact-version tarball integrity
|
||||
|
||||
Changes: Add a scoped fresh-cache registry probe, safe reproduction instructions and artifact ignore rule; record actual TLS-enabled metadata/download results and review handoff without selecting a stack or changing the harness.
|
||||
Validation: Original npm view command and verify.py returned exit 0; react@19.3.1 tarball (26394 bytes) matched registry SHA-512. make check passed validation and 66 tooling tests. git diff --check passed. App install/build and different-harness connectivity remain unverified.
|
||||
@@ -0,0 +1,56 @@
|
||||
# S00-011 executor evidence
|
||||
|
||||
Agent: auto-ci-cd-d105e8027730; role: ci-cd; date: 2026-10-15.
|
||||
Result: verified public npm metadata and integrity-checked exact-version tarball
|
||||
in the current fresh execution harness; awaiting independent security review.
|
||||
|
||||
## Actual changes
|
||||
|
||||
- experiments/0001-stack/registry-access/verify.py: dependency-free Python probe
|
||||
runs npm with explicit HTTPS registry/strict TLS, empty configs and fresh cache,
|
||||
retrieves react@19.3.1 without package scripts/install/extraction, checks exact
|
||||
version/URL and independently compares SHA-512 with registry metadata.
|
||||
- Scoped README documents exact command forms/options, observed public results,
|
||||
nonsecret environment prerequisites and limits. Scoped .gitignore excludes
|
||||
retrieved artifacts. No stack, runtime pin or shared interface was selected.
|
||||
- Task evidence/handoff/commit message only outside that source scope. No Git,
|
||||
harness, DNS, npm config, TLS, CORS, immutable specs or plan definitions changed.
|
||||
|
||||
## Commands and actual results
|
||||
|
||||
| Command | Exit | Result |
|
||||
| --- | --- | --- |
|
||||
| `python3 scripts/tasks.py resume --agent auto-ci-cd-d105e8027730` | 0 | Assigned S00-011 in_progress, no repeat claim. |
|
||||
| `python3 scripts/tasks.py show S00-011` | 0 | Bounded scope/acceptance read. |
|
||||
| `python3 scripts/tasks.py packet S00-011 --agent auto-ci-cd-d105e8027730` | 0 | Current requirements, dependency and no previous handoff. |
|
||||
| `npm view react version license engines --json --cache /private/tmp/luma-stack-npm-cache --fetch-retries=0 --fetch-timeout=15000` | 0 | Original failed command now returns version 19.3.1, license MIT, engines node >=0.10.0. |
|
||||
| `node --version` / `npm --version` / `npm config get strict-ssl` | 0 each | v26.3.0 / 11.16.0 / true. Observations only. |
|
||||
| `python3 experiments/0001-stack/registry-access/verify.py` | 0 | Both npm children exit 0, fresh-cache metadata/download, 26394-byte tarball; independent SHA-512 match. |
|
||||
| `make check` | 0 | Validated 276 tasks, 22 stages, 221 requirements, 211 allocated Web requirements, revision 7; all 66 tooling tests passed in 10.411s. Foundation integrity only. |
|
||||
| `git diff --check` | 0 | No tracked whitespace errors; scoped untracked files also inspected directly. |
|
||||
|
||||
Probe child commands and all options are recorded in the scoped README and source.
|
||||
Public URL: https://registry.npmjs.org/react/-/react-19.3.1.tgz
|
||||
|
||||
Observed registry and calculated integrity:
|
||||
`sha512-QNhWdt7nrgVWWQG58QuGsAR3jv3Hbe4mb4vz7w2csnHavciZJgda1CPNaldF6eVxv90ud3jUXpKlHL69gO38yw==`.
|
||||
Public metadata and result JSON plus actual tarball remain locally in ignored
|
||||
artifacts/. Security reviewer should regenerate them, not accept this text alone.
|
||||
|
||||
## Context and limits
|
||||
|
||||
Read assigned instructions/card/packet, NFR-007 in specs/tz_clear.md, accepted
|
||||
ADR 0000 and S00-001 executor/review evidence/handoff. S01 contracts remain future
|
||||
work and none are changed/needed. The initial working tree showed only the
|
||||
coordinator's state/tasks.json claim change. No S00-011 handoff or stack experiment
|
||||
directory existed initially; their read/list attempts returned missing-path errors,
|
||||
not test failures or evidence of a network blocker.
|
||||
|
||||
Current supplied harness has network enabled, workspace-write sandbox and never
|
||||
approval policy. No environment permission changes were necessary. The previous
|
||||
DNS failure no longer reproduces; the external correction mechanism is unknown.
|
||||
S00-002 must use registry-capable execution with TLS trust intact and perform its
|
||||
own version/license assessment, clean install/build and stack decision. Future or
|
||||
different harness connectivity, package signatures/provenance, browser/CORS,
|
||||
application build and app readiness are not verified by S00-011. No secrets or
|
||||
production account data were used. No dependency was added to the application.
|
||||
@@ -0,0 +1,21 @@
|
||||
# S00-011 handoff
|
||||
|
||||
Executor: auto-ci-cd-d105e8027730 (ci-cd).
|
||||
Result: the current fresh harness can reach the public npm registry with TLS
|
||||
verification enabled. The original npm view command returned exit 0. A fresh-cache
|
||||
probe retrieved react@19.3.1 (26394 bytes) and independently matched SHA-512 against
|
||||
registry metadata. No blocker; no external/harness configuration was modified.
|
||||
|
||||
Review the scoped README, verify.py and .gitignore under
|
||||
experiments/0001-stack/registry-access. Repeat the original npm view command and
|
||||
run `python3 experiments/0001-stack/registry-access/verify.py`; generated artifacts
|
||||
are ignored. Verify explicit strict TLS, exact package/origin, empty npmrc/fresh
|
||||
cache, ignored lifecycle scripts, independent integrity comparison and scope.
|
||||
Evidence: state/evidence/S00-011-auto-ci-cd-d105e8027730.md.
|
||||
|
||||
Security reviewer must independently accept or reject via CLI. Executor does not
|
||||
set done or unblock S00-002. After reviewed done, the coordinator queues a fresh
|
||||
S00-002 executor, which must retain working DNS/HTTPS egress and perform its own
|
||||
clean install/build. Current observed Node/npm versions and sample React version
|
||||
are not a stack selection. No app readiness, browser/provider behavior, signature
|
||||
verification or future/different-harness network availability is claimed.
|
||||
+31
-4
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"schema_version": 1,
|
||||
"revision": 6,
|
||||
"revision": 8,
|
||||
"tasks": {
|
||||
"S00-001": {
|
||||
"status": "done",
|
||||
@@ -1120,10 +1120,14 @@
|
||||
"owner": null
|
||||
},
|
||||
"S00-011": {
|
||||
"status": "todo",
|
||||
"owner": null,
|
||||
"status": "review",
|
||||
"owner": "auto-ci-cd-d105e8027730",
|
||||
"external_wait": false,
|
||||
"reason": "User authorized network access. runner.local.json now passes sandbox_workspace_write.network_access=true with workspace-write. Public npm metadata probe succeeded with TLS in a project-write/network-enabled Codex sandbox; S00-011 must independently verify the actual runner environment and package integrity before S00-002 is unblocked."
|
||||
"reason": null,
|
||||
"started_at": "2026-10-14T18:07:56+00:00",
|
||||
"updated_at": "2026-10-14T18:10:10+00:00",
|
||||
"evidence": "state/evidence/S00-011-auto-ci-cd-d105e8027730.md",
|
||||
"handoff": "state/handoffs/S00-011.md"
|
||||
}
|
||||
},
|
||||
"events": [
|
||||
@@ -1192,6 +1196,29 @@
|
||||
"task": "S00-011",
|
||||
"agent": "coordinator-network-0bc0fcf09c86",
|
||||
"reason": "User authorized network access. runner.local.json now passes sandbox_workspace_write.network_access=true with workspace-write. Public npm metadata probe succeeded with TLS in a project-write/network-enabled Codex sandbox; S00-011 must independently verify the actual runner environment and package integrity before S00-002 is unblocked."
|
||||
},
|
||||
{
|
||||
"revision": 7,
|
||||
"at": "2026-10-14T18:07:56+00:00",
|
||||
"action": "claim",
|
||||
"task": "S00-011",
|
||||
"agent": "auto-ci-cd-d105e8027730",
|
||||
"role": "ci-cd",
|
||||
"from": "todo",
|
||||
"to": "in_progress",
|
||||
"reason": null
|
||||
},
|
||||
{
|
||||
"revision": 8,
|
||||
"at": "2026-10-14T18:10:10+00:00",
|
||||
"action": "submit",
|
||||
"task": "S00-011",
|
||||
"agent": "auto-ci-cd-d105e8027730",
|
||||
"role": null,
|
||||
"from": "in_progress",
|
||||
"to": "review",
|
||||
"reason": null,
|
||||
"evidence": "state/evidence/S00-011-auto-ci-cd-d105e8027730.md"
|
||||
}
|
||||
],
|
||||
"retired_agents": [
|
||||
|
||||
Reference in new issue
Block a user