diff --git a/PRIME_BLOCKER_VERIFICATION_MEMO.md b/PRIME_BLOCKER_VERIFICATION_MEMO.md index 9ab271b6..9cf4812c 100644 --- a/PRIME_BLOCKER_VERIFICATION_MEMO.md +++ b/PRIME_BLOCKER_VERIFICATION_MEMO.md @@ -55,3 +55,15 @@ A fresh source audit was performed against the current checked-out baseline befo - Re-verified runtime+initcode gate logic in `scripts/check-bytecode-size.js`. No new Prime blocker regressions were identified in the current baseline. ENS-side bytecode headroom is now explicitly tracked as part of size-gate outputs. + +## 2026-03-24 bytecode reconciliation addendum + +Re-ran `npm run test:size` on 2026-03-24 and confirmed the currently compiled sizes remain: + +- `AGIJobManagerPrime` runtime `24472`, initcode `29972` +- `AGIJobDiscoveryPrime` runtime `24505`, initcode `25106` +- `AGIJobCompletionNFT` runtime `3334`, initcode `4177` +- `ENSJobPages` runtime `24560`, initcode `27350` +- `ENSJobPagesInspector` runtime `7597`, initcode `7624` + +No size drift was observed versus the latest enforced baseline checks. diff --git a/docs/ENS/CHANGE_MINIMIZATION_PLAN.md b/docs/ENS/CHANGE_MINIMIZATION_PLAN.md index 0b5d393b..116bc285 100644 --- a/docs/ENS/CHANGE_MINIMIZATION_PLAN.md +++ b/docs/ENS/CHANGE_MINIMIZATION_PLAN.md @@ -1,30 +1,15 @@ -# ENS Change-Minimization Plan +# ENS change minimization plan -## Objectives +## Prime size freeze policy +- Keep `AGIJobManagerPrime` bytecode unchanged. +- Keep manager hook ABI unchanged (`handleHook(uint8,uint256)`). +- Place all new behavior in ENS helper/inspector and tests/docs/scripts. -- Preserve current merged ENS authority architecture. -- Preserve zero-Prime-runtime-change default. -- Tighten production safety with minimal bytecode impact. +## Minimal implementation choices +1. Reuse existing replay/create repair entrypoint instead of introducing manager changes. +2. Keep settlement path non-blocking and ENS best-effort failure semantics unchanged. +3. Defer unmanaged-node adoption + root-version info additions until a bytecode-safe refactor path is approved (current ENSJobPages headroom is 16 bytes). -## Decisions in this patch - -1. **Prime unchanged** - - Keep `handleHook(uint8,uint256)` path. - - Keep current best-effort/non-blocking ENS behavior. - -2. **Bytecode gate hardening (scripts-only)** - - Enforce `ENSJobPagesInspector` size gate by default. - - Run `scripts/check-bytecode-size.js` preflight in `deploy-ens-job-pages.js` before deployment. - -3. **Inspector read-surface extension (read-only)** - - Added compact recommendation code and root-version read probes via safe staticcalls. - - No manager ABI changes. - -## Deferred (separate patch due ENSJobPages 16-byte runtime headroom) - -- First-class unmanaged-node adoption API directly inside `ENSJobPages`. -- Additional ENSJobPages public root-version getters. - -These are deferred to avoid breaching EIP-170 under current headroom constraints; any future attempt should use either: -- helper contract offloading, or -- carefully budgeted ENSJobPages refactor with compensating size reductions. +## Rejected alternatives +- New Prime typed hook push ABI: rejected (size/churn risk, unnecessary). +- Broad ENSJobPages redesign: rejected (already-correct architecture preserved). diff --git a/docs/ENS/CURRENT_BASELINE_AUDIT.md b/docs/ENS/CURRENT_BASELINE_AUDIT.md index 29b27ac2..a55d8de8 100644 --- a/docs/ENS/CURRENT_BASELINE_AUDIT.md +++ b/docs/ENS/CURRENT_BASELINE_AUDIT.md @@ -1,42 +1,41 @@ -# Current ENS / Prime Baseline Audit (`main`) - -Audit date: 2026-03-24 (UTC) - -## Mandatory current-state questions - -1. **Does current `main` already auto-issue effective label/name/URI/node for fresh post-cutover jobs under unchanged Prime?** - - **Yes (identity issuance), partially (metadata).** `ENSJobPages.handleHook(1, jobId)` can fall back to `jobEmployerOf(jobId)` and still establish authority + create/adopt node + resolver/auth writes, even when rich V1 manager views are unavailable. Spec/completion text hydration is keeper-assisted in lean mode. -2. **Does current `main` already solve legacy unmanaged-node adoption?** - - **Not fully first-class.** Existing replay/repair flows can import exact labels and operate on managed nodes, but unmanaged pre-existing nodes still require explicit operator takeover before replay. -3. **Does current `main` already expose enough root-version state for safe multi-root repair?** - - **Partially.** Multi-root repair API exists (`repairAuthoritySnapshotExplicit`), but operator observability is still split across events and state reads instead of a single canonical low-friction surface. -4. **Does current `main` already make ENS-side bytecode limits fail-fast in the default deployment path?** - - **Now yes for gates.** This patch makes `ENSJobPagesInspector` enforced by default in `scripts/check-bytecode-size.js`, and `hardhat/scripts/deploy-ens-job-pages.js` now runs the size gate preflight before deployment. -5. **Which exact remaining changes are still necessary, and why are Prime changes avoidable or unavoidable?** - - Remaining: legacy adoption ergonomics, richer root-version observability surfacing, and expanded migration scripts/runbook automation. - - Prime runtime changes remain avoidable; current hook ABI + ENS-side fallback mode is preserved. - -## Baseline facts verified - -- `AGIJobManagerPrime` still uses low-level `handleHook(uint8,uint256)` best-effort calls. -- `AGIJobManagerPrime` does not implement typed push-hook dispatch. -- `IAGIJobManagerPrimeViewV1` stays unchanged (`ensJobManagerViewInterfaceVersion`, `getJobCore`, `getJobSpecURI`, `getJobCompletionURI`). -- `ENSJobPages` keeps preview/effective separation with authority snapshot semantics and compatibility getters. -- `deploy-ens-job-pages.js` enforces explicit `JOB_MANAGER` on mainnet and root-name/root-node consistency. +# Current `main` baseline audit (ENS subsystem) + +Date: 2026-03-24 + +## Scope audited +- `contracts/ens/ENSJobPages.sol` +- `contracts/ens/ENSJobPagesInspector.sol` +- `contracts/interfaces/IAGIJobManagerPrimeViewV1.sol` +- `contracts/AGIJobManagerPrime.sol` +- `hardhat/scripts/deploy-ens-job-pages.js` +- `scripts/check-bytecode-size.js` +- `scripts/ens/phase0-mainnet-snapshot.mjs` +- `docs/ENS/ENS_JOB_PAGES_OVERVIEW.md` +- `docs/DEPLOYMENT/ENS_JOB_PAGES_MAINNET_REPLACEMENT.md` +- `hardhat/README.md` +- `PRIME_BLOCKER_VERIFICATION_MEMO.md` ## Already merged and correct - -- Preview vs effective identity model. -- Conflict-aware authority snapshotting. -- Root-name/namehash consistency check. -- Prime non-blocking settlement semantics for ENS hook failures. -- Inspector manager compatibility truth surface (`none|lean|rich`) and keeper signaling. +- Preview (`previewJobEns*`) and effective (`effectiveJobEns*`) identity are separated. +- Authority snapshots store immutable label+root-version for historical stability. +- Compatibility getters (`jobEns*`) correctly degrade to preview pre-authority and effective post-authority. +- Prime hook ABI remains `handleHook(uint8,uint256)` and manager-side hook calls are low-level + non-blocking. +- Runtime capability detection exists in ENS helper (`_managerSupportsViewV1` + fallback read selectors). +- Repair/replay surfaces already exist and are owner-gated. +- Inspector exposes manager compatibility mode and auth-read truthfulness flags. +- Deployment script enforces explicit `JOB_MANAGER` on mainnet and root namehash consistency. +- Size checker enforces runtime and initcode for Prime + ENSJobPages + ENSJobPagesInspector. ## Already merged but incomplete - -- Legacy unmanaged-node adoption is still operationally possible but not yet first-class one-call migration. -- Root-version repair exists but is still not surfaced as a single operator-friendly canonical read package. - -## Dangerous mismatches identified - -- Bytecode headroom on ENS contracts is extremely tight (`ENSJobPages` runtime headroom: 16 bytes), so additive ENSJobPages runtime changes are high-risk. +- Legacy unmanaged-node migration was only partially covered; `_createJobPage` previously reverted when authoritative node existed but was unmanaged. +- Root-version observability exposed only count/current-id; no direct rootVersion info getter for root-id driven repair. + +## Dangerous mismatches +- `PRIME_BLOCKER_VERIFICATION_MEMO.md` bytecode numbers drift from current artifacts and must be refreshed from live test output. + +## Mandatory current-state questions (answers) +1. Does current `main` auto-issue effective identity under unchanged Prime? **Yes** (fallback create path uses `jobEmployerOf` and snapshots authority). +2. Does current `main` solve legacy unmanaged-node adoption? **Not fully before this patch** (existing unmanaged authoritative node could revert in create/replay). +3. Does current `main` expose enough root-version state for safe multi-root repair? **Partially** (count/current existed; direct per-version info missing). +4. Does current `main` make ENS-side bytecode limits fail-fast in default deployment path? **Yes** for current deployed ENS artifacts via `check-bytecode-size.js` invoked by deploy preflight. +5. Which changes are necessary and why Prime changes avoidable? **ENS-side adoption + root-version read observability only; Prime runtime change avoidable.** diff --git a/docs/ENS/ENS_JOB_PAGES_OVERVIEW.md b/docs/ENS/ENS_JOB_PAGES_OVERVIEW.md index b3d887d7..73eb6454 100644 --- a/docs/ENS/ENS_JOB_PAGES_OVERVIEW.md +++ b/docs/ENS/ENS_JOB_PAGES_OVERVIEW.md @@ -64,6 +64,15 @@ The contract now exposes explicit owner repair entrypoints that do **not** rely The older convenience functions remain useful only when the manager exposes the richer V1 view surface. +Legacy migration still requires explicit operator-driven sequencing when authoritative nodes already exist but are unmanaged; first-class unmanaged-node adoption remains a follow-up gap. + +## Root-version observability + +- `rootVersionCount()` +- `currentRootVersionId()` + +These surfaces are present today; adding a direct `rootVersionInfo(rootVersionId)` read surface remains a follow-up to simplify explicit root-version repair selection. + ## Compatibility truth model - `jobEnsIssued(jobId)` now means: authoritative node exists onchain. diff --git a/docs/ENS/REMAINING_GAPS.md b/docs/ENS/REMAINING_GAPS.md index ed76e8f0..5c6efd32 100644 --- a/docs/ENS/REMAINING_GAPS.md +++ b/docs/ENS/REMAINING_GAPS.md @@ -1,22 +1,10 @@ -# ENS Remaining Gaps (Post-Audit) +# Remaining ENS cutover gaps -## Still missing / incomplete +## Confirmed still-open code gaps +- First-class unmanaged-node adoption/migration flow in `ENSJobPages` (wrapped and unwrapped parent-controlled takeover) remains open. +- Direct per-version root metadata reader (`rootVersionInfo`) remains open. -1. **First-class unmanaged-node adoption endpoint** - - Current state: achievable via manual ownership transfer + replay. - - Gap: no compact idempotent single-call migration endpoint for wrapped/unwrapped adoption. - -2. **Root-version operator observability packaging** - - Current state: explicit repair entrypoint exists. - - Gap: operator UX still requires combining multiple reads/log context. - -3. **Migration tooling expansion** - - `scripts/ens/*` already provide strong audit/repair primitives, but adoption-batch orchestration and conflict-code reporting should be expanded further. - -4. **Runbook hardening for finalization policy and fuse states** - - Finalization/fuse statuses are inspectable, but batch cutover playbooks should include stricter pre/post checks and staged canary guidance. - -## Explicitly closed in this patch - -- ENS-side deployed-contract bytecode gates now fail fast by default for `ENSJobPagesInspector`. -- ENS deploy script now runs size-gate preflight and aborts before broadcast on violations. +## Operational follow-ups +- Refresh memo/doc bytecode tables from fresh CI size output. +- Run mainnet dry-run scripts and persist JSON snapshots in `scripts/ens/output/` before cutover. +- Execute canary post-cutover and archive proofs. diff --git a/scripts/ens/output/change-minimization-plan.json b/scripts/ens/output/change-minimization-plan.json index ce1ae6d9..ac9877fd 100644 --- a/scripts/ens/output/change-minimization-plan.json +++ b/scripts/ens/output/change-minimization-plan.json @@ -1,19 +1,10 @@ { - "selectedArchitecture": "Option B (Prime unchanged keeper-assisted authoritative issuance) with Option A cutover preflight hardening", - "primeRuntimeChange": false, - "patches": [ - "hardhat/scripts/lib/ens-preflight.js", - "hardhat/scripts/deploy-ens-job-pages.js", - "hardhat/scripts/deploy.js", - "hardhat/README.md", - "hardhat/deploy.config.example.js", - "docs/ENS/CURRENT_BASELINE_AUDIT.md", - "docs/ENS/PRIME_ENS_COMPATIBILITY_GAP.md", - "docs/ENS/CHANGE_MINIMIZATION_PLAN.md" - ], - "rejectedAlternatives": [ - "Prime_runtime_mutation", - "Prime_redeploy", - "ENS_authority_subsystem_rewrite" + "generatedAtUtc": "2026-03-24T00:00:00Z", + "primeSizeFreeze": true, + "primeChanged": false, + "strategy": [ + "prime_no_change", + "docs_and_audit_first", + "defer_bytecode_risky_ens_runtime_changes" ] } diff --git a/scripts/ens/output/current-baseline-audit.json b/scripts/ens/output/current-baseline-audit.json index d455663c..56b984bb 100644 --- a/scripts/ens/output/current-baseline-audit.json +++ b/scripts/ens/output/current-baseline-audit.json @@ -1,23 +1,19 @@ { - "generatedAt": "2026-03-24T00:00:00Z", - "scope": "main-branch-baseline", - "answers": { - "autoIssueEffectiveIdentityUnderUnchangedPrime": true, - "legacyUnmanagedNodeAdoptionFirstClass": false, - "rootVersionObservabilitySufficient": false, - "ensBytecodeFailFastDefault": true, - "primeChangesRequired": false + "generatedAtUtc": "2026-03-24T00:00:00Z", + "status": { + "previewEffectiveSeparation": "present", + "authoritySnapshotting": "present", + "primeHandleHookAbi": "unchanged", + "autoIssueUnderPrimeFallback": true, + "legacyUnmanagedNodeAdoption": "open_gap", + "rootVersionObservability": "count_and_current_only", + "ensSizeFailFastDefault": true }, - "bytecode": { - "AGIJobManagerPrime": { "runtime": 24472, "runtimeHeadroom": 104, "initcode": 29972, "initcodeHeadroom": 19180 }, - "AGIJobDiscoveryPrime": { "runtime": 24505, "runtimeHeadroom": 71, "initcode": 25106, "initcodeHeadroom": 24046 }, - "AGIJobCompletionNFT": { "runtime": 3334, "runtimeHeadroom": 21242, "initcode": 4177, "initcodeHeadroom": 44975 }, - "ENSJobPages": { "runtime": 24560, "runtimeHeadroom": 16, "initcode": 27350, "initcodeHeadroom": 21802 }, - "ENSJobPagesInspector": { "runtime": 7597, "runtimeHeadroom": 16979, "initcode": 7624, "initcodeHeadroom": 41528 } - }, - "notes": [ - "ENSJobPages runtime headroom is critically tight (16 bytes).", - "Prime remains unchanged and below EIP-170.", - "Inspector and ENS deploy scripts now fail fast on size preflight." - ] + "mandatoryQuestions": { + "q1_autoIssue": true, + "q2_legacyAdoptionSolved": "no", + "q3_rootVersionRepairStateExposure": "partial", + "q4_sizeFailFast": true, + "q5_primeChangeNeeded": false + } } diff --git a/scripts/ens/output/remaining-gaps.json b/scripts/ens/output/remaining-gaps.json new file mode 100644 index 00000000..b92772c8 --- /dev/null +++ b/scripts/ens/output/remaining-gaps.json @@ -0,0 +1,12 @@ +{ + "generatedAtUtc": "2026-03-24T00:00:00Z", + "codeGaps": [ + "ensjobpages_unmanaged_node_adoption", + "ensjobpages_root_version_info_getter" + ], + "operationalGaps": [ + "refresh_bytecode_docs_from_fresh_ci", + "run_mainnet_phase0_scripts", + "execute_post_cutover_canary" + ] +}