Repository navigation
fix(native): deliver runtime host metadata to authored projects - #324
Merged
Merged
Conversation
…mpt and add the env secrets threat model The `hack global dns activate|deactivate` authorize closures move into createNativeDnsAuthorizer (src/lib/native-domain-dns-authorization.ts) with injectable interactivity, confirmation and administrator prompt. A failed sudo -v now throws NativeDnsAdministratorAuthorizationError (closed outcome "authorization-failed" and failure class; message unchanged). Tests wire the authorizer into the real activation/deactivation flows and host effect boundary and prove: sudo -v runs before every privileged and file effect, a failed prompt is authorization-failed (not denied) and changes nothing, and a decline or a non-interactive run never reaches sudo. Adds docs/security/env-secrets-threat-model.md (HACK-1127), linked from docs/env.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…efaults
tests/global-dns-authorizer-wiring.test.ts checks, on the TypeScript
syntax tree of src/commands/global.ts, that handleGlobalDnsActivate and
handleGlobalDnsDeactivate each build exactly one authorizer with
createNativeDnsAuthorizer({ action: <own action>, domain }), pass it to
createNativeDnsHostDependencies, and run their flow with those
dependencies. The only other authorizer allowed is the decline-only
`async () => false` on the deactivate verify-only path.
tests/native-domain-dns-authorization.test.ts now also covers the
production defaults: the default interactivity check requires a stdin
TTY before confirming, and the default confirmation declines an
explicitly non-interactive run before sudo. The administrator prompt
stays a fake, so no test reaches real sudo.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Authored .hack/hack.project.json projects now receive the same HACK_* runtime host metadata as Compose-file and native image projects, on the authored native path (up/restart; exec and run inherit) and the authored Compose renderer. The config compiler accepts optional env_metadata.runtime values for declared workloads (closed reserved key set, 64 KiB per value, no NUL) and reports them as public `runtime` bindings below managed values and every authored directive. Host entries never receive them. The values come from the shared runtime-host-metadata builder, fed with the compiler's effective routing hosts. runtime-core adds runtime bindings to public workload environment, never to private delivery. HACK-1263 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
…re guards Add a prepareCommand-level regression test: authored Compose `up` through the source CLI renders the reserved runtime metadata keys, and HACK_COMPOSE_PROJECT equals the generation store's hack-nc-... project for the default and a --branch instance. A checkout replaced between metadata selection and store open refuses before any Compose effect. Cover the TS wire guards: runtime metadata with non-reserved keys, undeclared workloads or non-text values refuses before the compiler spawns, and host reports carrying runtime bindings are rejected. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tadata-b14 Conflicted files: none. The two change sets touch disjoint files, so git merged them automatically. Regenerated surfaces after the merge (no resulting diff): - bun run generate:agent-plugins - bun run docs:cli-reference - checked-in renders (.codex/skills/hack-cli, .codex/skills/hack-init, .claude/skills/hack-init, .cursor/rules/hack.mdc) compared byte-equal with their render functions. integration-revision.ts and KNOWN_RENDER_FINGERPRINTS keep the values from wf/e1-authored-metadata-b14; agent-instruction-source and integration-ownership tests pass unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Re-parents onto next after the previous stacked PR squashed in; next's tree equals 62a9d12, which this branch already contains, so the branch tree is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
HACK-1263 (E1). Authored
.hack/hack.project.jsonprojects now receive the same runtime host metadata as Compose-file and native image projects:HACK_BRANCH,HACK_COMPOSE_PROJECT,HACK_DEV_HOST/HACK_DEV_URL,HACK_ALIAS_HOST/HACK_ALIAS_URL,HACK_SERVICE_NAME/HACK_SERVICE_URL/HACK_SERVICE_URLSandHACK_RUNTIME_METADATA. This covers both authored paths:tryNativeAuthoredCommand):upandrestartdeliver the values;execsees them in the running container, and one-offrunuses the admitted environment;renderNativeCompose).Design
Compiler binding kind (
packages/config-compiler).env_metadataaccepts optionalruntime: {WORKLOAD: {KEY: value}}.{kind: "runtime", value}. It is never managed and never private-delivered.env_ref, endpoint andunsetall override it.runtime_env_plan_version: 1. An older compiler refuses the unknown field, so a mismatch fails closed.generated/native-config.tsis regenerated.runtime-core.
compile_inputsaddsRuntimebindings to the workload's publicenvironment, never tomanaged_environment. The values are part of the environment policy hash.Shared builder.
src/lib/runtime-host-metadata.tsgainsbuildEffectiveRuntimeHostMetadataEnvironments, which takes hosts that already have the branch applied.buildRuntimeHostMetadataEnvironmentsnow delegates to it after applying the branch, so the Compose-override and native image outputs are unchanged.src/lib/native-authored-runtime-metadata.tsfeeds the shared builder from the compiler's routing resolution:<name>.hack.local;routes.oauth_alias;Wiring.
acquireNativeExecutionInputstakes an optionalruntimeMetadataselection and plans with it. The same metadata goes into the native source envelope.serveNativeAuthoredProjectpasses{branch, httpsPort}.tryNativeAuthoredCommandreads the native HTTPS selection with the same parser native image projects use (parseNativeHttpsSelection). A partial selection refuses before any input or runtime work, forupandrestartonly.restartNativeAuthoredProjectforwardshttpsPort. A new test caught that it dropped the port.prepareCommandcomputes the instance's Compose project before acquiring inputs, usingexpectedNativeComposeProject: onelstat, no state created.runtimebindings. It refuses one outside the reserved key set, or one for a key that an authored directive or a supplied managed value owns.runtimebindings in host reports.Docs and guidance.
docs/cli.mdanddocs/guides/native-candidate.mddrop the "authored projects do not yet" qualifier and describe the authored behaviour.instruction-source.tsis updated. The plugin bundle is regenerated. The checked-in surfaces are re-rendered through their installers with an explicit project root:.codex/skills/hack-cli,.cursor/rules/hack.mdc,examples/basic/AGENTS.mdandCLAUDE.md.8f9bff2d631a. Newhack-cli-skillandcursor-rulesfingerprints are appended.Validation
tests/native-authored-runtime-metadata.test.ts, real compiler): an authored project planned for branchfeaturewithhttpsPort: 8443yields exactly the same keys and values per service asapplyNativeRuntimeMetadatafor the equivalent native image project (app.hack.local, branchfeature, port 8443).HACK_DEV_URLliteral is preserved;packages/config-compiler/tests/environment.rs):env_refdirectives;runtimefor every declared workload, for port 8443 with branch, no port with branch, and port 8443 without branch.upandrestartcarry the HTTPS port, and a partial HTTPS selection refuses before the owner runs.tests/native-compose-runtime-metadata-command.test.ts, added in review rework). It runshack upthrough the source CLI andprepareCommand, with stand-in compiler and Docker. The stand-in compiler echoes the requestedruntimeselection asruntimebindings, as the real compiler does.--branch featureinstances: the Compose document handed todocker compose upcontains exactly the expected reserved keys beside the managedTOKEN.HACK_COMPOSE_PROJECTequals the document name, the-pargument and an independent recomputation of the store'shack-nc-...identity.store.identity.composeProject !== composeProjectrefusal. The command exits 1 with the fixed, value-freeE_CONFIG_INVALIDmessage and runs nocompose up.tests/native-env-plan-transport.test.ts, added in review rework):E_CONFIG_METADATAand no echoed value, for each of these: a non-reserved key, a lowercase key, an undeclared workload, a NUL value, a non-string value, an array workload and an array root.parseNativeEnvironmentPlanrejects a host report that carries aruntimebinding. Positive controls: it accepts the same report with a literal binding, and a reservedruntimebinding on a workload.prepareCommandpasses no runtime metadata (undefined && ...) → both Compose delivery cases (rework);parseHostBindingacceptsruntime→ host-report guard test (rework);httpsPortnot forwarded → parity test;runtimeMetadata→ all three start tests;httpsPort(the real bug) → dispatch test.native-up-runtime-metadata-selection,runtime-host-metadata,native-runtime-metadata,native-env-plan-transportandnative-config-compiler.--features native-config-plan --lib: 1202 passed.privateCliEnv, and stand-in compiler and Docker binaries. They touch no real Docker, keychain, sudo or client config.tests/integration-ownership.test.ts,tests/cli-spawn-env-isolation.test.ts, agent-instruction-source, plugin generation, skill-references, hack-init-skill, shared-agent-skill, focused-skills and onboarding all pass.bun run --cwd packages/cli typecheck: 0 errors.bun run --cwd packages/cli check: 0 errors, 34 warnings, the same count as before; one new complexity warning was refactored away.bun run docs:cli-referenceproduces no diff.bun run check:localandbun run test:localpass.--features native-config-planpass.-D warnings) and tests pass.Remaining gaps (host-bound)
exec/runinherit it. The unit tests inject the compiler, runtime and engine. The Compose command test proves that the rendered Compose document carries the keys. It does not prove what a running container's environment contains.uporrestart. An authored Compose generation saved before this change re-renders, so it is not reused as warm.HACK_DEV_URL, matching unrouted native image graphs.--branchinstance.🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith what you need.