chore(builder): delete dead env declarations, pin the eval escape hatch, close residue
Opus review round on the self-improvement-keyless capstone commit, 2
Important + 3 Minor, all residue (no custody defects):
- env.d.ts: delete the three dead VECTOR_SPEND_LIMIT_PER_TX/_DAILY/
VECTOR_AUDIT_LOG_PATH ambient declarations - safety.ts was their only
reader and it's deleted. The capstone custody PR should not leave
live-looking spend-limit declarations behind.
- boundary.test.ts: new mechanical pin asserting self-improvement.ts never
references localUPLCEval - the test-only eval escape hatch on
buildProposalSpend may never be passed from a tool handler. Proved
load-bearing: applied the mutation (a 4th { localUPLCEval: true } arg),
watched it fail by name, reverted, confirmed a byte-identical diff against
the mutation (git diff --stat showed only the unrelated storageUri
simplification below), re-ran green.
- rate-limit-gating.test.ts: reworded the now-false "self-improvement.ts is
the remaining compiler-blind case" comment - both tool-registration files
are typed now; the timing-based hermeticity rationale stands on its own.
- types.ts + gov-build.ts + self-improvement.ts: added optional storageUri
to VectorBuildStakeResult, set by buildCritique only; the critique tool
handler now renders r.storageUri directly instead of reconstructing
ipfs://${ipfsCid}, removing the duplicated URI-format knowledge. Result
types are not wire schemas - zero snapshot drift confirmed.
- registry-build.ts:303: "governance family" -> "self-improvement family".
Gate: typecheck 0 (3 packages) - unit 392/392 (391 + the new eval-escape-hatch
pin) - smoke 27/27, 24 tools, zero snapshot drift - auth 12/12 - boundary
5/5 (4 custody + the new pin). Custody grep re-confirmed empty.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
7
packages/builder/src/env.d.ts
vendored
7
packages/builder/src/env.d.ts
vendored
@@ -5,12 +5,5 @@ declare namespace NodeJS {
|
||||
VECTOR_KOIOS_URL: string;
|
||||
VECTOR_SUBMIT_URL: string;
|
||||
VECTOR_EXPLORER_URL: string;
|
||||
|
||||
// Safety Limits
|
||||
VECTOR_SPEND_LIMIT_PER_TX: string;
|
||||
VECTOR_SPEND_LIMIT_DAILY: string;
|
||||
|
||||
// Audit Log
|
||||
VECTOR_AUDIT_LOG_PATH: string;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -455,6 +455,7 @@ export async function buildCritique(lucid: LucidEvolution, p: {
|
||||
proposalRef: `${p.proposalTxHash}#${p.proposalOutputIndex}`,
|
||||
stakeLovelace: stakeLovelace.toString(),
|
||||
scriptAddress: critiqueSpendAddress,
|
||||
storageUri: finalUri,
|
||||
...(ipfsCid ? { ipfsCid, documentHash } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -300,7 +300,7 @@ export async function buildDeregisterAgent(
|
||||
// REGISTRY_POLICY_ID above) does NOT match the in-workspace Aiken source
|
||||
// under agent-infrastructure/contracts/agent-registry/ - that source
|
||||
// compiles to policy 5dd51189..., a different script entirely (confirmed
|
||||
// by hashing both; provenance worth resolving before the governance
|
||||
// by hashing both; provenance worth resolving before the self-improvement
|
||||
// family trusts that source as ground truth). Differential-tested
|
||||
// directly against the deployed bytecode instead: deregister enforces a
|
||||
// floor on the owner's returned change - a sole-input deregister of a
|
||||
|
||||
@@ -463,7 +463,6 @@ This transaction is valid until ${new Date(r.validToMs).toISOString()} (about 6
|
||||
const r = await buildCritique(lucid, {
|
||||
agentDid, proposalTxHash, proposalOutputIndex, critiqueType, stakeApex, critiqueDocument, critiqueHash, storageUri,
|
||||
});
|
||||
const storageDisplay = r.ipfsCid ? `ipfs://${r.ipfsCid}` : storageUri;
|
||||
return {
|
||||
content: [{
|
||||
type: "text" as const,
|
||||
@@ -472,7 +471,7 @@ This transaction is valid until ${new Date(r.validToMs).toISOString()} (about 6
|
||||
**Type:** ${critiqueType}
|
||||
**Stake:** ${stakeApex} AP3X
|
||||
**Proposal:** ${proposalTxHash}#${proposalOutputIndex}
|
||||
**Storage:** ${storageDisplay}
|
||||
**Storage:** ${r.storageUri}
|
||||
${r.ipfsCid ? `**IPFS CID:** ${r.ipfsCid}\n**Hash (auto-computed):** ${r.documentHash}\n` : ''}
|
||||
**Script Address:** ${r.scriptAddress}
|
||||
**Estimated Fee:** ${r.feeAda} AP3X
|
||||
|
||||
@@ -101,3 +101,32 @@ describe('builder custody boundary', () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// A second, narrower mechanical guard, same style as the custody boundary
|
||||
// above but for a different invariant: gov-build.ts's buildProposalSpend
|
||||
// exposes a 4th, TEST-ONLY `opts?: { localUPLCEval?: boolean }` parameter
|
||||
// (documented in-source as an escape hatch used only by gov-build.test.ts's
|
||||
// native-eval-attempt test - see gov-build.ts). Every production caller,
|
||||
// including self-improvement.ts's vector_build_self_improvement_proposal_spend
|
||||
// handler, must omit it and get gov-build.ts's own default
|
||||
// (`opts?.localUPLCEval ?? false` - provider-side eval, parity with the
|
||||
// deployed module). Nothing in the hermetic or smoke suites would notice a
|
||||
// handler mutation that passed `{ localUPLCEval: true }` as a 4th argument:
|
||||
// gov-build.test.ts tests buildProposalSpend directly (not through the tool
|
||||
// handler), and the smoke suite only inspects tool schemas/descriptions, not
|
||||
// handler bodies. This test closes that gap the same mechanical way the
|
||||
// custody boundary above closes the mnemonic gap: by asserting on the
|
||||
// compiled source text itself.
|
||||
describe('self-improvement.ts never touches the test-only eval escape hatch', () => {
|
||||
test('the test-only eval escape hatch may never be passed from a tool handler', () => {
|
||||
const content = readFileSync(join(SRC_ROOT, 'vector/self-improvement.ts'), 'utf-8');
|
||||
assert.doesNotMatch(
|
||||
content,
|
||||
/localUPLCEval/,
|
||||
'self-improvement.ts must never reference localUPLCEval - the test-only eval escape hatch may never be passed from a tool handler; ' +
|
||||
'production callers always get gov-build.ts\'s own default (provider-side eval, parity with the deployed module). ' +
|
||||
'If buildProposalSpend is now being called with a 4th argument from a tool handler, remove it - that argument exists only for ' +
|
||||
'gov-build.test.ts\'s native-eval-attempt test.',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -10,9 +10,14 @@ import type { RawServerHandle } from '../setup.ts';
|
||||
// unit-tests RateLimiter/limiterFor in isolation; test:smoke only ever calls
|
||||
// listTools(). Neither exercises a single tool handler, so neither would
|
||||
// notice checkRateLimit/rateLimiter falling out of scope in agent-network.ts
|
||||
// or self-improvement.ts. agent-network.ts is typed now, so tsc catches a
|
||||
// scoping regression there; self-improvement.ts (typed in the
|
||||
// self-improvement-keyless PR) is the remaining compiler-blind case. See
|
||||
// or self-improvement.ts. Both files are typed now (self-improvement.ts as of
|
||||
// the self-improvement-keyless PR) - no compiler-blind tool-registration file
|
||||
// remains in the builder - but tsc alone still can't catch this class of bug:
|
||||
// a handler that silently drops the `if (rateLimited) return rateLimited;`
|
||||
// early-return typechecks fine (the function still returns the right shape),
|
||||
// it just never gets called at runtime unless a real request exercises it.
|
||||
// This test's timing-based hermeticity rationale stands on its own for that
|
||||
// reason, independent of which files happen to be typed. See
|
||||
// .superpowers/sdd/pr5-integration-tests-report.md for the mutation-testing
|
||||
// evidence.
|
||||
//
|
||||
|
||||
@@ -143,6 +143,7 @@ export interface VectorBuildStakeResult extends VectorUnsignedBuildResult {
|
||||
scriptAddress: string;
|
||||
ipfsCid?: string;
|
||||
documentHash?: string;
|
||||
storageUri?: string; // set by buildCritique only - buildEndorse has no document/URI concept
|
||||
}
|
||||
|
||||
export interface VectorBuildProposalLockResult extends VectorUnsignedBuildResult {
|
||||
|
||||
Reference in New Issue
Block a user