Stage E: per-injection human-approval gate; reject --yes on hardware; fix _confirm(twin=True)
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 52/100
Research direction
Start with the CDSBackend inject/read path and the Stage A fakes described in the acceptance criteria, then inspect src/system_ident/cli.py and src/system_ident/backends/base.py. Confirm that each injection requires a single-use approval, denied approvals prevent construction or start, EOFError denies by default, and hardware rejects --yes with exit 2.
Written by the indexing model from the issue text.
Description
Stage E (spec §1, §5). Enforce in code the hardware-safety rules now in
CLAUDE.md: only humans authorize the hardware, and each individual injection needs separate
approval — one approval never carries over.
The sibling project enforces neither in code — no input(), no --confirm, no dry-run on its hardware
path; the rules are documentation-only there. This repo should do better, because it already has most of
the machinery.
The gate goes inside CDSBackend.inject()
It is the only code path from any caller to the actuator, and the only place holding the actual samples.
Rejected alternatives, and why:
- A
Watchdogpre-injection hook or aloop.pychange is a convention, not an invariant: any script,
notebook or test that constructs the backend and callsinject()directly bypasses it entirely. It also
makesSysIDLoopbackend-aware, contradictingsrc/system_ident/backends/base.py:3("the loop and
the safety handoff use only these methods, so simulation and hardware are truly interchangeable"), and
the watchdog has no access to the drive array so it cannot show the operator what is about to happen. - A decorator or mixin has the same bypass risk unless applied at class level, at which point it is
the inject-internal gate with extra indirection.
Approval is a single-use token
Staging and actuation are now separate (inject() stages, read() executes), so approval granted at
inject() is for an actuation that happens later:
inject()prompts — printing channel, hardware rate, duration, RMS, peak and crest, and the
start_gpswindow — then mints_approval[channel].read()refuses to start any staged injection whose token is missing or consumed; consumes it on
start.- Re-reads of an already-running injection do not re-prompt: nothing new is actuated. A new
inject()
mints a new token. That is Rule 2 exactly. - The prompt is injectable (
authorizer=) for testability, and defaults to deny onEOFError/
non-TTY. Never proceed in batch.
Fix the existing CLI gate
src/system_ident/cli.py:89calls_confirm(twin=True)unconditionally, so the"HARDWARE"
label atsrc/system_ident/cli.py:129is dead code and a hardware run would announce itself as a
twin run →_confirm(twin=args.twin or args.rtsfreerun).--yes(src/system_ident/cli.py:45) is a campaign-wide skip, i.e. by definition a carry-over
approval, which Rule 2 forbids → reject it at argparse level (exit 2) when neither--twinnor
--rtsfreerunis given. The CLI prompt then becomes a pre-flight; the gate is the token.
Acceptance — tests that assert it cannot be skipped
All on the Stage A fakes:
- Denying authorizer → raises, and
FakeArbitraryLoopwas never constructed (assert the construction
counter, not.start). - Authorizer called exactly twice for two
inject()calls; exactly once for oneinject()+ three
read()s. read()with a staged-but-unapproved injection → raises,.startnever called.- Default authorizer with
inputraisingEOFError→ denies. main(["run", cfg, "--yes"])without--twin→ exit 2.
Campaign: CDS hardware backend · branch feat/cds-hardware-backend
· spec · plan · handoff
Code is deferred until the plan and issues have been reviewed.
- Dominant language
- Python
- Stars
- 0
- Forks
- 1
- PR merge metrics
- No merged PRs in 30d
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from CaltechExperimentalGravity/system_ident
-
Difficulty 4/5 3-5 days Newbie friendliness 35/100
-
enhancement
Difficulty 5/5 Over a week Newbie friendliness 15/100
-
enhancement
Difficulty 5/5 Over a week Newbie friendliness 35/100
-
enhancement
Difficulty 5/5 Over a week Newbie friendliness 35/100
-
enhancement
Difficulty 5/5 Over a week Newbie friendliness 25/100
All issues in CaltechExperimentalGravity/system_ident
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
sylvainmetayer/homelab#851 ·
Maintainers usually reply within 1 day
-
needs triage
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
kubeflow/docs-agent#279 ·
Maintainers usually reply within 3 days
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 67/100
Qiskit/qiskit-ibm-runtime#3523 ·
Maintainers usually reply within 1 day