Repository navigation
Add a second Anthropic API key entry to the credential inventory - #889
Merged
Merged
Conversation
Add the optional anthropic-api-2 entry directly after anthropic-api. It mirrors the first entry's class, status, lane, variables, consumers and store kind, with its own env file, loader and rotation text. It is an additional key: nothing is replaced, and the setter, the runner and the guard are unchanged. - docs/secret-storage.md lists both Anthropic entries and how one command selects a key. - tests/test_credential_run.py expects eleven injectable ids instead of ten and adds one test that the setter and the runner treat both ids alike, using a temporary store and generated fake values. - The first entry's note on why the key variable stays out of the shell is corrected to match Claude Code's current guidance (headless mode uses a present key; interactive mode asks once first), and the correction is recorded in the anti-pattern log of docs/harness-defaults.md. - docs/decisions/2026-10-08-anthropic-api-second-key.md records the decision, its sources, the alpaca-paper-2 precedent and the inverse. - manifests/evidence.json is refreshed with host_receipts.register_file. No credential value or store was read. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Drop the sentence about a skill applied before editing, and state the unmeasured boundaries (key type, workspace spend limits, installed consumer acceptance and provider execution) directly instead of attributing them to a reviewer. Nothing in the repository can verify either claim. No other wording changes. manifests/evidence.json is refreshed for the record with host_receipts.register_file. Co-Authored-By: Claude Opus 5.5 <[email protected]>
The lines this branch adds to docs/secret-storage.md move its telemetry section down 18 lines. Update the five source locators in catalogs/foundation/upstream-surface-dispositions.json that cite those lines (the telemetry switch and its four content flags), so that each cited line names its key again. Only the line numbers change: no disposition, reason or test is edited. tests.test_upstream_surface_watch failed five subtests of DispositionCitationTests.test_every_cited_line_names_the_key on the previous head and passes with this change. manifests/evidence.json is refreshed for the catalog with host_receipts.register_file. Co-Authored-By: Claude Opus 5.5 <[email protected]>
blueprints/runtime-workers/openhands/resolver/patch_policy.py cited docs/secret-storage.md:199-200 for the directory that the repository's relative core.hooksPath names. Those lines are about the runner's masking and its output path, on main as well as on this branch; the statement was already elsewhere (lines 412-413) when the comment was written in 3b8f9c8. The comment now cites 442-443, where the page sets `git config core.hooksPath scripts/git-hooks` and notes that the relative path makes each worktree run its own checkout's hook. Only the comment changes; the file keeps its line count. The citation of docs/harness-defaults.md:208 in push_gate.py is left as it is: its list ends "(at 56fced8)", and at that commit line 208 is the instruction-file row the comment refers to. manifests/evidence.json is refreshed for the file with host_receipts.register_file. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…ate it" This reverts commit 67d9e8d. The stale citation in patch_policy.py predates this pull request and is outside its scope; it will be handled separately. With this revert the tree is identical to 75fa64b's again: patch_policy.py and its registered hash in manifests/evidence.json return to their previous content. Co-Authored-By: Claude Opus 5.5 <[email protected]>
seathatflowsinourveins
marked this pull request as ready for review
October 8, 2026 23:14
seathatflowsinourveins
added a commit
that referenced
this pull request
Oct 9, 2026
main moved to aba02ec (#889 and others), and manifests/evidence.json conflicted, so no pull_request workflow ran on the branch. The manifest is resolved by the hot-file protocol: main's copy, then this branch's seven changed files re-registered with host_receipts.register_file, followed by component_matrix.py --write and new_host_grand_list.py --write; validate.py exits 0. Co-Authored-By: Claude Opus 5.5 <[email protected]>
seathatflowsinourveins
added a commit
that referenced
this pull request
Oct 9, 2026
main moved to aba02ec (#889 and others), and manifests/evidence.json conflicted, so no pull_request workflow ran on the branch. The manifest is resolved by the hot-file protocol: main's copy, then this branch's 8 changed files re-registered with host_receipts.register_file, followed by component_matrix.py --write and new_host_grand_list.py --write; validate.py exits 0. Co-Authored-By: Claude Opus 5.5 <[email protected]>
seathatflowsinourveins
added a commit
that referenced
this pull request
Oct 9, 2026
main moved to aba02ec (#889 and others), and manifests/evidence.json conflicted, so no pull_request workflow ran on the branch. The manifest is resolved by the hot-file protocol: main's copy, then this branch's 8 changed files re-registered with host_receipts.register_file, followed by component_matrix.py --write and new_host_grand_list.py --write; validate.py exits 0. Co-Authored-By: Claude Opus 5.5 <[email protected]>
seathatflowsinourveins
added a commit
that referenced
this pull request
Oct 9, 2026
main moved to aba02ec (#889 and others), and manifests/evidence.json conflicted, so no pull_request workflow ran on the branch. The manifest is resolved by the hot-file protocol: main's copy, then this branch's 7 changed files re-registered with host_receipts.register_file, followed by component_matrix.py --write and new_host_grand_list.py --write; validate.py exits 0. Co-Authored-By: Claude Opus 5.5 <[email protected]>
6 of 8 tasks
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.
Scope
anthropic-api-2entry directly afteranthropic-apiinadoption/credential-inventory.json, so one command can select an additional Console key. It is an additional key: nothing is replaced. The setter, the runner and the guard are unchanged: the setter and the runner read the inventory, and the guard's rules already cover the variable and the whole store directory. Both entries declare onlyANTHROPIC_API_KEY, which stays inmust_not_be_set.e48de2e6fa1dd3b740af4793ea5824ea35476dbalane:foundationadoption/credential-inventory.json,docs/secret-storage.md,docs/decisions/2026-10-08-anthropic-api-second-key.md,docs/harness-defaults.md,tests/test_credential_run.py,catalogs/foundation/upstream-surface-dispositions.json, andmanifests/evidence.json(the hashes of those six files, written byscripts/host_receipts.py:register_file).The new entry differs from the first in exactly six fields:
id,label,store.path_template(fileanthropic-api-2.envin the same directory),loaders,rotationandnotes. Class, status, lane, variables, optional and pointer variables, consumers and store kind are identical. The repository precedent isalpaca-paper-2(#481,c26800f3).Scope beyond the brief. Four edits go beyond adding the entry. They are declared here so that the read of this PR covers them:
notesis corrected. Old: "exported in a shell it would override every Claude Code session's native sign-in". New: "a shell export can switch Claude Code from subscription sign-in to API billing (headless mode uses the key when present; interactive mode first asks for approval)". Source: Claude Code's environment variables page, where a present key is always used in non-interactive mode (-p) and is approved once in interactive mode before it overrides the subscription. The new entry gives the same reason, so the two entries agree. No other field ofanthropic-apichanges.docs/harness-defaults.md. It records that correction, which that page's "Record a correction the same turn" rule asks for.docs/secret-storage.mdgains the first key's table row as well. The entry table had noanthropic-apirow. It now lists both entries, followed by one paragraph on selecting a key for one command.docs/secret-storage.mdare updated incatalogs/foundation/upstream-surface-dispositions.json, because the added rows moved the cited lines down by 18. Thesourcelocators ofCLAUDE_CODE_ENABLE_TELEMETRY(1697 → 1715),OTEL_LOG_USER_PROMPTSandOTEL_LOG_ASSISTANT_RESPONSES(1684 → 1702), andOTEL_LOG_TOOL_CONTENTandOTEL_LOG_RAW_API_BODIES(1686 → 1704) change; no disposition or reason does. Hostedvalidate-shard-3failed five subtests ofDispositionCitationTests.test_every_cited_line_names_the_keyat88d981c7; Declare the optional public EdgarTools request cap #858 made the same repair for its own insertion.SOTA sources
Public primary documentation, fetched 2026-10-08; every cited anchor resolves.
ANTHROPIC_API_KEYautomatically, and a key scoped to one workspace needs no workspace header.anthropic-workspace-idheader; spend limits are set per workspace.-p) a present key is always used; in interactive mode the key is approved once before it overrides the subscription. These support the corrected wording.c9ab2212142398234b6ba39a4cf33c5c2a6a643e, the reference implementation this change follows; the cited files are unchanged at the base commit: inventory entriesanthropic-api(Add the anthropic-api credential entry for local tools #841,a35369aa) andalpaca-paper-2;tools/credentials/set_credential.py:load_entry;tools/credentials/credential_run.py:find_entryandinjectable; the guard'sSECRET_NAMES,STORE_PATHSandENV_FILE_WORDinscripts/hooks/secret_path_guard.py; theRunnerCasefixtures intests/test_credential_run.py;scripts/host_receipts.py:register_fileandscripts/validate.py. No credential runtime or dependency is added.Evidence-class table
anthropic-api, onlynoteschangesorigin/main, using the runner's owninjectable()InjectionTests.test_second_anthropic_key_uses_the_same_setter_and_runner_grammar: temporary store, generated fake valuesSTORE_PATHSandSECRET_NAMESin the guard;tests.test_secret_path_guard;guard.read_commandon nine synthetic command forms returns the same reason for both ids (four store-path formscredential_store_path, the documented runner form allowed)betterleaks dir1.9.0 with.gitleaks.tomlon a copy of those six files: no leaks, rc 0. The required gate is CI's pinned gitleaks 8.30.1, which is not installed on this host; hostedsecret-scanpassed at88d981c7tests.test_upstream_surface_watch: 5 of 128 repository citations failed with the catalog at88d981c7, 0 fail now. Of 263 line citations into the four edited files, 126 point past the inserted lines: these 5; 46 pinned to a commit; 75 in dated records, frozen evidence or code comments that already pointed elsewhere before this PR or carry their own source revisionNot measured here: the actual key type, the workspace spend limit, credit, fast mode and provider acceptance. A multi-workspace key needs the
anthropic-workspace-idheader and is outside this single-variable entry.Every changed existing test expectation
One constant changes, and two existing tests assert on it. The exact injectable set was
alpaca-paper,alpaca-paper-2,sec-contact,databento,typesafe,omniroute,tavily,claude-oauth-token,canary-e2eandanthropic-api.INJECTABLE_IDSnow adds onlyanthropic-api-2.InjectionTests.test_only_the_selected_entrys_own_pointer_variables_stay_in_the_childanthropic-api-2, whose own pointer list is empty.InventoryAndGrammarTests.test_every_injected_name_is_masked_or_publicanthropic-api-2. The exact optional-variable classification is unchanged, because the new entry has none.No other existing assertion is edited.
NOT_INJECTABLE_IDSis unchanged. The status module checks the canonical inventory dynamically and by subset. The boot-receipt allowlist test compares the receipt's rows with the canonical inventory, so its expected id sequence follows the inventory (20 → 21 rows; file-kind rows 18 → 19). The guard's tie tests read the inventory's variable and pointer names, which do not change. Fixtures are unchanged.InjectionTests.test_second_anthropic_key_uses_the_same_setter_and_runner_grammaris new coverage, not a relaxed assertion.Local commands run
One module per command (no suite discovery). The twelve modules below ran on the tree committed as
5117734b, the first commit one48de2e6. The second commit,88d981c7, only removes two process claims from the decision record that nothing in the repository can verify; the docs module and the validator were run again on its tree. The third commit,75fa64b3, re-points five catalog citations; the last block covers it and the whole suite.On the tree committed as
88d981c7:Hosted validate at
88d981c7(run 37846469750) failed one shard:validate-shard-3,Ran 1514 tests,FAILED (failures=5, skipped=127). All five failures were the stale catalog citations. The third commit,75fa64b3, fixes them. On its tree:The 21 nonzero modules all passed in hosted validate at
88d981c7. Locally they fail for host reasons, not because of this diff:exchange_calendarsis not installed in this host's Python 3.13. Hosted installs 4.13.2 from.github/requirements-calendar.txt. Sixteen modules do not import: the 13test_adaptive_paper_*modules other than credential_race, plustest_alpaca_admission_regressions,test_native_faults_minandtest_order_throughput.test_ingest_snapshothas 2 errors.test_adaptive_paper_credential_racehas 5 mutation self-test failures, because its pristine run imports the runner module. All 18 fail the same way on a checkout of the basee48de2e6.test_token_e2e_grader:git clone --localfrom the worktree (on disk) into/tmp(tmpfs) fails withInvalid cross-device link. It passes on the base checkout, which lives on tmpfs.test_windows_terminal_defaults: the Claude Code client installed on this host reports aplugin_notificationnotification type that has no repository decision. The base gives the same failure.test_new_wsl_mcp_conformance_lifecycle: host-state dependent. Three runs at this head gave a listener assertion, a missingcleanup.json, then a pass; it passes on the base.The fourth commit,
67d9e8d5, corrected a stale comment citation inblueprints/runtime-workers/openhands/resolver/patch_policy.py. That citation was already wrong on main, so it is outside this PR's scope and will be handled separately. The fifth commit,2fa607e1, reverts it. The head's tree is identical to75fa64b3's (treed399373a). On it,timeout 900 python3 scripts/validate.pyreturns rc 0.Decision record
docs/decisions/2026-10-08-anthropic-api-second-key.md: the decision, the handling rules, the sources, thealpaca-paper-2precedent, the correction, the evidence boundaries, the alternatives and what would reopen the decision, and the inverse.Host evidence
Not applicable: this PR adds or changes no file under
evidence/hosts/.Checklist
Landing notes
anthropic-adminat the same position in the inventory and edits the sameINJECTABLE_IDSline; IBKR paper gateway signs in by itself: stored paper login by pointer, rootless container owner rule in the credential checker, adopted recreate script #769 and Recover and check Codex profiles alongside shared credential pointers #770 (drafts) also touch the inventory,docs/secret-storage.mdandtests/test_credential_run.py. Whichever lands second needs a rebase and a freshregister_filepass.🤖 Generated with Claude Code