Skip to content

Credential inventory: alpaca-paper-c slot for paper account C; the guard reads a one-letter pointer suffix - #1014

Merged
seathatflowsinourveins merged 2 commits into
mainfrom
cc/credential-account-c-20261011
Oct 11, 2026
Merged

seathatflowsinourveins merged 2 commits into
mainfrom
cc/credential-account-c-20261011

Conversation

@seathatflowsinourveins

@seathatflowsinourveins seathatflowsinourveins commented Oct 11, 2026 •

Copy link
Copy Markdown
Collaborator

Scope

  • What this PR changes, in one or two sentences: Adds the alpaca-paper-c slot (Alpaca paper account C for the agent-run paper lane C, lane us-equities-paper-c, pointer PAPER_ENV_FILE_C) to the native credential inventory. Because that pointer has a letter suffix, the secret-path guard now reads a one-letter suffix as it reads _2, so $PAPER_ENV_FILE_C is guarded like the other paper pointers.
  • Base commit: 99e72aef. The branch was cut at bcf55c45 and rebased once before this PR opened, because fix: prevent landscape workers deleting shared scratch #987 also changed adoption/hooks/claude/SHA256SUMS and manifests/evidence.json. The pin file merged cleanly. The manifest was rebuilt by re-registering this PR's eight files over main's copy.
  • Lane: lane:foundation
  • Owned paths touched: adoption/credential-inventory.json, adoption/hooks/claude/SHA256SUMS, scripts/hooks/secret_path_guard.py, tools/credentials/set_credential.py, docs/secret-storage.md, catalogs/foundation/upstream-surface-dispositions.json (five line citations rebound), tests/test_secret_path_guard.py, tests/test_credential_status.py, tests/test_credential_run.py, tests/test_credential_tools.py, tests/test_credential_boot_receipt.py; manifests/evidence.json (re-registered hashes only).
  • Commits:
    • a2410e21 adds the slot and the guard change.
    • 95227f34 fixes what CI found at a2410e21. Validate-shard-5 failed tests.test_upstream_surface_watch (DispositionCitationTests.test_every_cited_line_names_the_key) five times: the two runbook lines moved docs/secret-storage.md lines 1713, 1715 and 1726 to 1715, 1717 and 1728, which the dispositions catalog cites by number. The fix rebinds them as Add two optional direct Anthropic Console key stores #930 did.
    • The same commit fits the guard's comment and pattern back into the five lines they had, so no later guard line moves. This keeps the unpinned guard citations in docs/decisions/2026-10-08-guard-hook-fails-closed.md (5184-5188, 5208-5213) accurate. The pattern is the same in both commits.

The guard change adds a host step. After merge, the user-scope guard copy must be reinstalled with tools/adoption/install_claude_profile.py --only guard. Until then tests.test_secret_path_guard.test_host_profile_copy_is_verbatim fails on a host (it skips in CI). Once main carries the new pin, guard_matches_pin (in scripts/credential_status.py) also reads false for the old installed copy. That second point is read from the source and was not run.

The new row:

  • label "Alpaca paper broker key pair, account C (agent-native paper lane)", class broker_api_key_pair, status optional (it becomes required only when account C activates), lane us-equities-paper-c;
  • store private_env_file at ${XDG_CONFIG_HOME:-$HOME/.config}/native-agent-stack/alpaca-paper-c.env;
  • the same variables, optional_variables and public_variables as alpaca-paper-2, and pointer_variables ["PAPER_ENV_FILE_C"];
  • loaders and environment_only_consumers empty, which the checker's inventory_errors accepts (as for databento); the activation change names the loader;
  • rotation and notes worded like alpaca-paper-2's: paper-only keys, never live.

No store file was created or read. The owner enters the keys from their own terminal.

SOTA sources

  • The inventory's own decision and runbook, at base bcf55c45:
    • docs/decisions/2026-09-24-secret-storage.md is the store layout that this row follows: one provider per 0600 file under the 0700 store root.
    • docs/secret-storage.md is the runbook. Its inventory table and its shell-profile pointer block each gain one line.
    • The checker named in the inventory's checker field, scripts/credential_status.py (inventory_errors), enforces the schema.
  • Pattern precedent: Guard: a numbered pointer such as PAPER_ENV_FILE_2 is a credential pointer; alpaca-paper-2 inventory row #481 (c26800f3) added alpaca-paper-2 and the numeric pointer suffix. It used the same failing-first tie test (test_inventory_pointer_variables_are_guarded) and the same row-by-row check of each new BLOCKED row against the previous guard.
  • Mechanism of the guard change: CPython Doc/library/re.rst at v3.13.16 (python/cpython cbc944f4bc59, the local upstream mirror).
    • The \b entry (lines 551-561) defines a boundary as one between a \w and a \W character.
    • The \w entry (lines 639-644) counts the underscore as a word character.
    • So \b after PAPER_ENV_FILE cannot match before _C, and the old suffix group (?:_[0-9]+)? could not consume _C.
    • The hook runs under /usr/bin/python3 3.14.4 and CI under 3.12.3. These entries document the same semantics for str patterns.
  • Consumer of the slot: us-equities-trading at 2904e25.
    • session-scopes/paper-agent-native/guards/credential-deny-sources.json pins this inventory and records account_C_allocation_verified: false.
    • docs/decisions/2026-10-09-trading-ecosystem-addendum.md:54 requires that account C's credential pointer resolve to account C's paper keys and nothing else.

Evidence-class table

Claim Evidence class Command / receipt
The new row is a valid inventory entry and the checker reports it local_integration scripts/credential_status.py on a fixture home: rc 0, row ok, result ok. Also tests.test_credential_status rc 0
Before the change, $PAPER_ENV_FILE_C readers, sources and dumps passed the guard local_integration Base guard with the new rows: tests.test_secret_path_guard rc 1, 41 failures. Each of the 10 new BLOCKED rows returns None from the base guard
After the change they are blocked, and the account-C loader, size and systemd-run forms still pass local_integration CI=true python3 -m unittest tests.test_secret_path_guard rc 0
Entering a live-shaped (AK) key id into the account-C slot is flagged synthetic tests.test_credential_tools rc 0. It was rc 1 with the base set_credential.py
The boot receipt names the new row and stays value-free synthetic tests.test_credential_boot_receipt rc 0. Fixture credential_boot_receipt.py record rc 0: rows 24, unsafe 0, and the fake value is absent from every output
\b and \w semantics source_review CPython Doc/library/re.rst at cbc944f4bc59

Local commands run

All commands ran in the PR worktree with TMPDIR under /var/tmp. The fixture runs set HOME, XDG_CONFIG_HOME and XDG_STATE_HOME to a scratch fixture home and pass an empty --proc-keys fixture, so no real store, key file or /proc/keys was read.

# failing first: base scripts/hooks/secret_path_guard.py and tools/credentials/set_credential.py, new inventory row and test rows
$ python3 -m unittest tests.test_secret_path_guard
rc=1  Ran 90 tests  FAILED (failures=41, skipped=2)
      10 test_blocked_commands, 20 test_every_rule_applies_behind_rtk_proxy,
      10 test_every_rule_applies_to_a_keyring_exec, 1 test_inventory_pointer_variables_are_guarded
$ python3 -m unittest tests.test_credential_tools
rc=1  Ran 35 tests  FAILED (failures=1)  test_account_c_paper_slot_gets_the_same_prefix_hint

# with the change
$ python3 -m unittest tests.test_secret_path_guard
rc=1  Ran 90 tests  FAILED (failures=1, skipped=2)  test_host_profile_copy_is_verbatim only:
      the host's installed guard is still the pre-change copy (reinstall after merge; skipped in CI)
$ CI=true python3 -m unittest tests.test_secret_path_guard
rc=0  Ran 90 tests  OK (skipped=3)
$ python3 -m unittest tests.test_credential_status
rc=0  Ran 50 tests  OK
$ python3 -m unittest tests.test_credential_run
rc=0  Ran 94 tests  OK
$ python3 -m unittest tests.test_credential_tools
rc=0  Ran 35 tests  OK
$ python3 -m unittest tests.test_credential_boot_receipt
rc=0  Ran 21 tests  OK
$ python3 -m unittest <the 27 other modules that load the inventory, SHA256SUMS, the guard or set_credential.py>
rc=0  Ran 2312 tests  OK (skipped=151)      # at the pre-rebase head on bcf55c45

# after the rebase onto 99e72aef (#987 changed the hook pin file and the token-lanes hooks)
$ python3 -m unittest tests.test_secret_path_guard        rc=1, test_host_profile_copy_is_verbatim only (as above)
$ CI=true python3 -m unittest tests.test_secret_path_guard
rc=0  Ran 90 tests  OK (skipped=3)
$ python3 -m unittest tests.test_credential_status tests.test_credential_run tests.test_credential_tools \
    tests.test_credential_boot_receipt tests.test_install_claude_profile tests.test_token_lanes_session_start \
    tests.test_token_lanes_subagent_start tests.test_adoption_docs_consistency tests.test_adoption_status \
    tests.test_effort_default_guard     # run one module at a time
rc=0 for each: 50, 94, 35, 21, 116 (skipped=1), 14, 23, 39 (skipped=1), 141 and 28 tests OK
$ (cd adoption/hooks/claude && sha256sum -c --quiet SHA256SUMS)
rc=0
$ python3 -I scripts/credential_status.py --root . --proc-keys <empty fixture> --json      # fixture home
rc=0  alpaca-paper-c: state ok, status optional, lane us-equities-paper-c, findings []; result ok
$ python3 -I scripts/credential_boot_receipt.py --proc-keys <empty fixture> record         # fixture home
rc=0  rows=24 ok=1 missing=21 unsafe=0 ... result=ok
$ python3 -I scripts/credential_boot_receipt.py --proc-keys <empty fixture> compare
rc=0
$ python3 scripts/validate.py
rc=0  {"components": 70, "hashed_files": 11632, "profiles": 4, "receipts": 239, "status": "passed"}
$ python3 scripts/evidence_manifest.py --check
rc=0  {"files": 11632, "status": "passed"}
$ gitleaks git --log-opts="origin/main..HEAD" --redact --no-banner --config .gitleaks.toml .   # 8.30.1
rc=0  no leaks found

# CI at a2410e21: validate-shard-5 failed (tests.test_upstream_surface_watch, 5 failures, the shifted citations); fixed at 95227f34
$ python3 -m unittest tests.test_upstream_surface_watch
rc=0  Ran 114 tests  OK (skipped=6)
$ python3 -m unittest tests.test_secret_path_guard        rc=1, test_host_profile_copy_is_verbatim only
$ CI=true python3 -m unittest tests.test_secret_path_guard
rc=0  Ran 90 tests  OK (skipped=3)
$ python3 -m unittest tests.test_install_claude_profile tests.test_adoption_docs_consistency tests.test_adoption_status \
    tests.test_effort_default_guard tests.test_credential_status tests.test_credential_boot_receipt   # one module at a time
rc=0 for each: 116 (skipped=1), 39 (skipped=1), 141, 28, 50 and 21 tests OK
$ python3 scripts/validate.py
rc=0  {"components": 70, "hashed_files": 11632, "profiles": 4, "receipts": 239, "status": "passed"}
$ python3 scripts/evidence_manifest.py --check; (cd adoption/hooks/claude && sha256sum -c --quiet SHA256SUMS)
rc=0; rc=0

manifests/evidence.json was updated with scripts/host_receipts.py's register_file for the nine changed files it already registered. tests/test_credential_boot_receipt.py and tools/credentials/set_credential.py were not registered before and are still not registered.

Decision record

No new record. The slot follows docs/decisions/2026-09-24-secret-storage.md. The command center allocated account C's slot id and lane on 2026-10-11, and account C's activation is decided in us-equities-trading. A guard change that read every uppercase suffix (_[A-Z0-9]+) was not chosen. Measured by patching it into a scratch copy of the guard, it refuses ordinary reads such as cat "$ENV_FILE_DIR/README" and cat "$PAPER_ENV_FILE_LIST" as credential_file_read, and the chosen pattern passes both. The recorded gap is now a suffix of two or more letters.

Host evidence

Not applicable: no file under evidence/hosts/ changes.

Checklist

  • New/changed GitHub Actions are pinned to a full commit SHA with a
    version comment (no floating tags). No workflow changes.
  • New/changed workflows declare top-level permissions: {} and grant each job
    only what it needs (contents: read, or an explicitly justified addition). No workflow changes.
  • No secrets are printed, logged or committed; no new required secret was
    added without a documented owner. The new slot is optional, and the owner enters its keys.
  • No new paid hosting, subscription or billing surface was introduced.
  • Peer-owned untracked files and worktrees were preserved (not deleted,
    moved or overwritten).

Follow-ups

  • Owner: create or choose the Alpaca paper account for lane C. Enter its keys from your own terminal with tools/credentials/open_credential_terminal.sh alpaca-paper-c. Use paper keys only: an AK-prefixed key id is flagged.
  • Host, after merge: reinstall the user-scope guard with python3 tools/adoption/install_claude_profile.py --only guard. Then test_host_profile_copy_is_verbatim passes, and guard_matches_pin reads true.
  • us-equities-trading activation change:
    • Update session-scopes/paper-agent-native/guards/credential-deny-sources.json: source_pin, inventory_sha256, an alpaca-paper-c entry with deny path ~/.config/native-agent-stack/alpaca-paper-c.env and pointer PAPER_ENV_FILE_C, and account_C_allocation_verified.
    • Name the loader. The checker resolves any loaders or environment_only_consumers reference that contains a / and no space against this repository's root, so a us-equities-trading path needs a form the checker accepts. One such form is the id-based runner line tools/credentials/credential_run.py alpaca-paper-c -- <command>. Another is a follow-up here that names the consumer.
  • Here, when account C activates: set the row's status to required and record the loader in this inventory.
  • A host that holds account C's file: add export PAPER_ENV_FILE_C="$_nas_store/alpaca-paper-c.env" to the shell profile, as the runbook block now shows.
  • Already stale at base, not changed here: blueprints/runtime-workers/openhands/resolver/patch_policy.py:137 cites docs/secret-storage.md:199-200 for core.hooksPath. At bcf55c45 those lines already held other text (the masking list), so the citation needs rebinding to the section it means.

🤖 Generated with Claude Code

…ard reads a one-letter pointer suffix

Adds the account-C paper credential slot that the command center allocated on
2026-10-11 for the agent-run paper lane C of us-equities-trading
(session-scopes/paper-agent-native): inventory id alpaca-paper-c, lane
us-equities-paper-c, store <store>/alpaca-paper-c.env, pointer PAPER_ENV_FILE_C,
the variables, optional variables and public variables of alpaca-paper-2, status
optional, and no loader or consumer until the change that activates account C
names one. The owner enters the keys from their own terminal; no store file was
created or read.

Guard: POINTER_VARIABLE took a numeric suffix only, so the word boundary after
PAPER_ENV_FILE failed before `_C` (`_` is a word character: CPython
Doc/library/re.rst, the `\b` and `\w` entries, v3.13.16 at cbc944f4bc59), and a
reader, a redirect, a traced source and a declare -p or %ENV dump after sourcing
"$PAPER_ENV_FILE_C" each passed while the account-1 and account-2 forms were
blocked. The suffix may now also be one uppercase letter, which closes the
recorded `$PAPER_ENV_FILE_B` gap too; a longer suffix (`_AB`) stays a recorded
gap.

Failing first, with the base guard and set_credential.py and the new inventory
row and test rows: tests.test_secret_path_guard rc=1 with 41 failures
(test_inventory_pointer_variables_are_guarded for PAPER_ENV_FILE_C, the ten new
BLOCKED rows in test_blocked_commands, and their 20 rtk-proxy and 10
keyring-exec derivations; each new BLOCKED row returns None from the base
guard), and tests.test_credential_tools rc=1 with 1 failure
(test_account_c_paper_slot_gets_the_same_prefix_hint). Both pass with the change.

Also: KEY_PREFIX_HINT gains alpaca-paper-c: PK, so a live-shaped AK key id is
flagged at entry; the runbook gets the table row and the shell-profile pointer
line; INJECTABLE_IDS and the public-variable classification name the new id; a
status test mirrors account 1; the value-free receipt test plants the new store
file; SHA256SUMS carries the new guard hash; and the changed registered files are
re-registered in manifests/evidence.json.

After merge, a host reinstalls the guard with
tools/adoption/install_claude_profile.py --only guard
(tests.test_secret_path_guard.test_host_profile_copy_is_verbatim fails locally
until then and skips in CI).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@seathatflowsinourveins seathatflowsinourveins added the lane:foundation Foundation lane: Claude/Codex setup, hosts, memory, RAG, research, workers label Oct 11, 2026
…mbers

CI (validate-shard-5, run 38164637938, at a2410e2) failed
tests.test_upstream_surface_watch
DispositionCitationTests.test_every_cited_line_names_the_key five times. The two
runbook lines this PR adds moved docs/secret-storage.md lines 1713, 1715 and
1726 to 1715, 1717 and 1728, and catalogs/foundation/upstream-surface-dispositions.json
cites those lines by number. The five sources are rebound, as #930 did for its
rows; the module passes again (114 tests, skipped 6).

The guard's pointer comment and pattern now fit the five lines they had at the
base, so every later line keeps its number and the unpinned citations of the
guard in docs/decisions/2026-10-08-guard-hook-fails-closed.md (lines 5184-5188
and 5208-5213) still hold. The pattern itself is unchanged. SHA256SUMS carries
the new guard hash, and the three changed files are re-registered.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@seathatflowsinourveins
seathatflowsinourveins marked this pull request as ready for review October 11, 2026 19:34
@seathatflowsinourveins
seathatflowsinourveins merged commit ccff876 into main Oct 11, 2026
35 checks passed
@seathatflowsinourveins
seathatflowsinourveins deleted the cc/credential-account-c-20261011 branch October 11, 2026 22:24
seathatflowsinourveins added a commit that referenced this pull request Oct 12, 2026
Fix the decision record of the compounding rule text,
docs/decisions/2026-10-11-compounding-rule-text.md. The six rule
surfaces do not change.

- Approval: the owner approved section 1's proposal, the first
  sentence, at 22:01Z. The second sentence was presented as an optional
  clause and the owner's answer did not single it out; the command
  center (CC) included it under the owner's delegation, because it
  restates the owner's own no-dates direction. The owner was told at
  23:44Z, with the option to drop it. The record cites the ruling's
  addendum-01 and the SHA256 of each sentence.
- #172: restated with its recorded supersession at 22:18:17Z, under
  which guard bypasses are follow-ups (research-queue row 23). #1014
  landed as ccff876 with only the one-letter POINTER_VARIABLE suffix.
- PR triage: 3 fold receivers (#878, #927, #958) merged without their
  4 donors (#804, #915, #870, #829), citing the triage's addendum-01.
- What the second sentence leaves in force (F1 of the trading lane's
  read of us-equities-trading #87): it forbids a date as the trigger
  that starts work, and every time bound the contract states as a fact
  or protocol window stays.
- Checks: the budget test's sentence now says what the test does (the
  first GPT read of this PR):
  test_growth_in_any_loaded_file_crosses_the_fixed_budget fills the
  available headroom in each loaded file in turn, verifies that
  equality with the ceiling passes, then appends a two-byte UTF-8
  character and verifies rejection.
- manifests/evidence.json: the record re-registered with register_file.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
seathatflowsinourveins added a commit that referenced this pull request Oct 12, 2026
…1020)

* Rule text: work compounds through reviewed, cited repository records

Add the compounding sentences of the command center's ruling, section 1
(sentence 1 owner-OK'd at 22:01Z; sentence 2 included under the owner's
delegation, ruling addendum-01), to the "The ecosystem compounds" bullet
on all six always-loaded rule surfaces: AGENTS.md, the portable Claude
block, the Codex template, the scaffold and the two new-WSL carriers,
regenerated with new_wsl_client_config.py --write-blocks.

- tests: a fail-first test that every layer and native renderer carries
  the sentences once, in place (9 failing subtests before the change);
  CORE updated; the Codex top-rule pin re-derived (2,296 bytes); the
  startup byte ceilings raised by a dated comparison to 6,895/7,001.
- docs/decisions/2026-10-11-compounding-rule-text.md: the dated trigger,
  evidence, surfaces, user-level pickup, budget comparison, checks and
  overturn conditions.
- manifests/evidence.json: the changed files re-registered.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* Record text: exact approval, #172 supersession, fold count, budget test

Fix the decision record of the compounding rule text,
docs/decisions/2026-10-11-compounding-rule-text.md. The six rule
surfaces do not change.

- Approval: the owner approved section 1's proposal, the first
  sentence, at 22:01Z. The second sentence was presented as an optional
  clause and the owner's answer did not single it out; the command
  center (CC) included it under the owner's delegation, because it
  restates the owner's own no-dates direction. The owner was told at
  23:44Z, with the option to drop it. The record cites the ruling's
  addendum-01 and the SHA256 of each sentence.
- #172: restated with its recorded supersession at 22:18:17Z, under
  which guard bypasses are follow-ups (research-queue row 23). #1014
  landed as ccff876 with only the one-letter POINTER_VARIABLE suffix.
- PR triage: 3 fold receivers (#878, #927, #958) merged without their
  4 donors (#804, #915, #870, #829), citing the triage's addendum-01.
- What the second sentence leaves in force (F1 of the trading lane's
  read of us-equities-trading #87): it forbids a date as the trigger
  that starts work, and every time bound the contract states as a fact
  or protocol window stays.
- Checks: the budget test's sentence now says what the test does (the
  first GPT read of this PR):
  test_growth_in_any_loaded_file_crosses_the_fixed_budget fills the
  available headroom in each loaded file in turn, verifies that
  equality with the ceiling passes, then appends a two-byte UTF-8
  character and verifies rejection.
- manifests/evidence.json: the record re-registered with register_file.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lane:foundation Foundation lane: Claude/Codex setup, hosts, memory, RAG, research, workers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant