Decisions & CI
The conversational workflow doesn’t just resolve a single audit run — it can capture the decisions you made into project rules that live in your repo. CI then runs Demeanor against those rules with no AI in the pipeline.
The shape of the loop. The audit runs and finds a pattern it isn’t certain about. The assistant relays it. You decide. The assistant offers to capture that decision as a project rule. You approve, the rule lands in .demeanor/patterns/, you commit it. The next audit run — on your machine, on a teammate’s machine, in CI — treats the pattern as resolved.
Why durable artifacts matter
A conversational audit that doesn’t leave anything behind has a problem: every subsequent run starts from zero. The same finding comes up tomorrow, you make the same decision tomorrow, the assistant relays it tomorrow. The work doesn’t compound.
The fix is to write the decision down. Specifically, to write it down in a form Demeanor can read on the next run, with no human and no assistant in the loop. That form is a project rule: a JSON file under .demeanor/patterns/, committed to git, picked up by the audit automatically.
Two consequences fall out of that:
- The conversation produces something concrete. What changed isn’t in chat history — it’s in your repo, visible in
git diff, reviewable in a PR. - CI doesn’t need an assistant. The build server reads the same rule files your interactive run read. The audit behaves the same way. The protection is identical.
The loop, step by step
- Demeanor runs the audit. The audit is Demeanor’s job, not the assistant’s. It reads your compiled assemblies, matches them against the built-in rule set plus anything in
.demeanor/patterns/, and emits a classified report. - The assistant relays the findings. Auto-protected matches are summarised. Advisories are mentioned. Needs-decision findings come with the audit’s recommendation, the file and line they originated from, and a brief explanation of why the audit can’t decide on its own.
- You make the decision. Some decisions are immediate — “protect that, it’s an internal plugin contract.” Some require thought — “let me check whether anyone outside the repo calls this.” The assistant waits.
- The assistant proposes a project rule. If your decision generalises — “protect every type that implements this interface,” not just the one type that fired today — the assistant offers to capture it as a rule. You see the JSON before it’s written. Severity, match, rationale, all visible.
- You approve, the file lands. The new rule appears under
.demeanor/patterns/. The assistant re-runs the audit to prove the rule fires correctly on the originating finding. The PR diff shows the new file alongside any source changes. - CI runs Demeanor. On the next build, the obfuscator reads the same rule file. The pattern is auto-protected without anyone in the loop. The chat session is gone; the rule remains.
Steps 4 and 5 are the part that matters. Without them you have a faster audit; with them you have a compounding one.
Three beats — this is the whole pitch
Standalone audit
Install Demeanor, run demeanor audit, read the report. No AI subscription, no MCP client, no LLM involvement. This is the canonical path and it is fully sufficient for shipping protected code.
Optional conversational relay
If you already use an MCP-capable assistant, drive the same audit as a chat. The assistant reads your source, relays findings against the right file and line, proposes fixes Demeanor recommended, edits on your approval. Same audit, conversational surface.
Decisions become rules
The decisions you made in step 2 become project rules in your repo. Future audits — including CI — apply them automatically. The conversation produces a durable artifact, then steps out of the way. CI never needs an AI.
Most marketing about AI tooling stops at beat 2 — “chat with your tool.” That works until you turn the chat off and lose the context. Demeanor’s loop is engineered so beat 3 is the point, not an afterthought.
What CI actually runs
CI runs the same obfuscator binary you ran locally, with the same rule set. There is no “CI mode.” The build:
- Restores
WiseOwl.Demeanor.MSBuildviadotnet restore. - Builds Release.
- The package’s
.targetsfile invokes the obfuscator after the compile step. - The obfuscator reads
.demeanor/patterns/from the repo root, the built-in rule set from itself, your[Obfuscation]attributes from the assembly, and anyDemeanorExcludeitems from MSBuild. - The obfuscation runs. Auto-protect rules take effect silently. Advisory rules log to the build output. Needs-decision rules cause the build to fail, because there’s no human to ask.
That last point is the key invariant. If CI builds green, you know every rule in your repo is either auto-protect or advisory — no decisions are silently outstanding.
A minimal GitHub Actions step
- run: dotnet build -c Release
env:
DEMEANOR_LICENSE: ${{ secrets.DEMEANOR_LICENSE }} No special invocation. No MCP server starts. No assistant runs. The build is hermetic with respect to AI.
What lives in git
Three categories of decision get committed alongside your code:
1. Project rules
JSON files under .demeanor/patterns/. These are the team-wide rules — matched by shape, applied automatically. See the rule structure.
2. The decisions log
A versioned JSON document recording every needs-decision finding and how it was resolved. Lives at .demeanor/decisions.json alongside your project rules. Each write replaces the whole file atomically (read, mutate in memory, write a temp file, swap into place) so the document is always a valid snapshot. Future audits read it to remember decisions that don’t generalise to a rule — “leave this specific method alone, the caller is in a separate repo we control.”
3. [Obfuscation] attributes in source
The classic source-level mechanism. Still the right answer when the exclusion belongs to this type and only this type. Exclusions Guide.
These three carry your team’s judgement forward across builds, branches, and developers. Together they are the durable substrate — the audit is just the lens that reads them.
Local overrides without polluting the repo
Sometimes you need to test a rule before you commit it — or apply a one-off override that doesn’t belong to the team. Two layers exist for that:
- User layer — rules under your home directory, applied to every Demeanor run on your machine. Useful for personal conventions across multiple projects.
- Session layer — in-memory rules that exist only for the current run. The conversational workflow uses this when you decide “just this once” and don’t want a rule file written.
Both layers shadow lower layers, so a user or session rule with the same id as a project rule wins for that run. Neither is committed; neither affects CI.
What this looks like in a PR
The pattern that makes this work in a team setting: every new rule shows up in code review. A PR that adds a project rule contains the JSON file under .demeanor/patterns/ alongside any source changes. Reviewers see:
- The
id— a stable identifier. - The
title— what the rule does in one line. - The
severity— auto-protect, needs-decision, or advisory. - The
match— what the rule applies to. - The
rationale— why this rule belongs in the repo.
Reviewers can ask “is this match too broad?” or “should this be advisory instead of auto-protect?” the same way they ask about any other code change. The audit’s judgements are no longer locked inside the tool; they are reviewable artifacts.
How this fits with the other mechanisms
Demeanor has several ways to influence the audit and obfuscation. Each has a place:
| Mechanism | Best for | Lives in |
|---|---|---|
| Built-in rules | The common .NET frameworks and serialization stacks | Inside Demeanor |
| Project rules | Your team’s patterns — matched by shape | .demeanor/patterns/ |
| Decisions log | One-off resolutions that don’t generalise | .demeanor/decisions.json |
[Obfuscation] attribute | Pinning one specific type or member from source | The source file |
| CLI / MSBuild excludes | Quick diagnostic without rebuilding from source | Command line or .csproj |
If you only ever touch [Obfuscation] attributes, Demeanor still works. The rule layer is what scales the audit across a team — particularly when paired with the conversational workflow that proposes rules instead of asking the same question every run.
Next steps
- Rules — the layered rule store and how a project rule is structured
- Conversational walkthrough — a real audit session, including the rule-promotion turn at the end
- Conversational workflow — setup for customers who already use an MCP-capable assistant
- CI/CD Integration — the build-side details, secrets, and report archiving