Skip to content

feat: destination-conditional synthetic marker + attestation + deployment boundary (roadmap #3) - #91

Merged
404SecNotFound merged 2 commits into
mainfrom
feat/conditional-synthetic-marker
Sep 1, 2026
Merged

feat: destination-conditional synthetic marker + attestation + deployment boundary (roadmap #3)#91
404SecNotFound merged 2 commits into
mainfrom
feat/conditional-synthetic-marker

Conversation

@404SecNotFound

Copy link
Copy Markdown
Owner

Roadmap 2026-09 item 3, the gate precondition for any live pilot. Folds in #1 (manifest attestation) and #5 (deployment-boundary doc) as the governance layer that makes the marker coherent.

What changed

  • Destination-conditional default (Orchestrator._resolve_marker): the synthetic marker is now ON by default for a non-loopback send, OFF for --to-file and loopback (where the golden line is the oracle). flexString1 is a flex slot none of the three vendor profiles populate, so marking a live send corrupts no field a detection reads. Both fidelity leads conceded this in the debate.
  • Overrides: --mark-synthetic forces it on everywhere; new --no-marker forces it off and logs a warning when it overrides a non-loopback send. no_marker wins over benign_marker.
  • Manifest attestation: new marker_attestation field on RunManifest and ScenarioManifest records the decision and why, so a run's marking is auditable. Defaulted, so old manifests still load.
  • Applied at the existing _mark choke point, so run, scenario, and the connect test all follow one rule. Loopback detection is conservative: anything not confidently loopback (including a hostname we will not resolve) is treated as non-loopback, so ambiguity resolves to "mark it".
  • docs/deployment-boundary.md: the "detection lab, not production SIEM" boundary and the authorization workflow (marker on + manifest as the record). Referenced from the README safety table and CLAUDE.md safety rules.

Positive control (definition of done)

The six new tests in tests/test_synthetic_marker.py were run against the unfixed code and observed to fail (the end-to-end case shows lines captured but unmarked, assert False), then pass after the change. Full suite: 1057 passed; black/ruff/mypy clean.

Decision record: docs/roadmap-2026-09.md (#89).

… + deployment boundary

Roadmap 2026-09 item 3 (folds in #1 attestation and #5 deployment
boundary). The single control that keeps Replicant from being banned the
first time it burns a shift.

- Marker default is now destination-conditional (Orchestrator._resolve_marker):
  ON for a non-loopback send, where analyst de-confliction on a shared
  collector outranks a flex slot no detection reads; OFF for --to-file and
  loopback, where the golden line is the oracle. flexString1 is unused by all
  three vendor profiles, so marking a live send corrupts no field a rule keys on.
- --mark-synthetic forces it on everywhere; new --no-marker forces it off and
  logs a warning when it overrides a non-loopback send (settings.no_marker,
  which wins over benign_marker).
- Manifest records the decision in a new marker_attestation field (RunManifest
  and ScenarioManifest), so a run's marking is auditable after the fact.
- Applied uniformly through the existing _mark choke point, so run, scenario,
  and the connect test all follow the same rule.
- docs/deployment-boundary.md states the 'detection lab, not production SIEM'
  boundary and the authorization workflow (marker on + manifest as the record).

Positive control: the six new tests in test_synthetic_marker.py were run
against the unfixed code and observed to fail (the end-to-end one shows lines
captured but unmarked); they pass after the change. 1057 tests, gates clean.
From /code-review on PR #91, verified against the code before fixing:

1. (main) Web /api/connect/test sent an UNMARKED line to a non-loopback
   collector while the CLI send_test marked it: the recurring 'fixed one
   send path, not the parallel one' class. server.connect_test now resolves
   the marker per destination like the CLI. Positive control: reverted the
   line, web guard went red, restored it green.
2. Scenario sends carried the literal flexString1=synthetic with no run id
   to trace them. run_scenario now generates a run_id, threads it into the
   emit path, and records it in ScenarioManifest (new run_id field), so a
   marked scenario line traces back to its manifest.
3. marker_attestation claimed a '--no-marker override' even on loopback/file
   where the default was already off; now only a real override is reported so.
4. Docs said 'off for --to-file' flatly; a run that both sends live and writes
   a file marks both (the file mirrors the wire). Wording made precise across
   README, CLAUDE.md, deployment-boundary, settings, and the docstring.
5. The --no-marker warning read as if lines were emitted though it resolves at
   plan time; reworded as configuration intent.

+3 guards (web probe marking, loopback attestation, scenario run-id marking).
1060 tests, black/ruff/mypy clean.
@404SecNotFound
404SecNotFound merged commit d97cd78 into main Sep 1, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant