@crewhaus/boundary-classifier 0.2.4 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -11,7 +11,7 @@ export declare class BoundaryClassifierError extends CrewhausError {
11
11
  * Adding a new origin? Update `OriginDefaultSeverity` and the §41 doctor
12
12
  * check at the same time.
13
13
  */
14
- export type TrustOrigin = "user" | "mcp" | "subagent" | "channel" | "federation" | "skill" | "compaction" | "tool" | "chain";
14
+ export type TrustOrigin = "user" | "mcp" | "subagent" | "channel" | "federation" | "skill" | "compaction" | "tool" | "chain" | "memory";
15
15
  export type BoundarySeverity = "block" | "warn" | "pass";
16
16
  export type BoundaryAction = "pass" | "warn" | "redact";
17
17
  export type ClassifyBoundaryOptions = {
package/dist/index.js CHANGED
@@ -70,6 +70,14 @@ const ORIGIN_DEFAULT_POLICY = {
70
70
  // or an event-emitting contract can plant malicious strings in event payloads
71
71
  // that get decoded and injected into the model's context. Block by default.
72
72
  chain: "block",
73
+ // Memory content (0.3.0 design §7.4): recalled wiki articles, recalled
74
+ // facts, and dream-synthesis output. A wiki article written in an earlier
75
+ // session may have absorbed attacker text (a poisoned web page STUDYed
76
+ // into an article, a malicious MCP response captured as a fact) — recall
77
+ // re-injects it across a session boundary, so it must be re-verified at
78
+ // read time. Block by default, same tier as "skill" (both are
79
+ // disk-persisted instructions-adjacent content).
80
+ memory: "block",
73
81
  };
74
82
  /**
75
83
  * In-process LRU cache over `(sha256(content), origin)` → result. The
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crewhaus/boundary-classifier",
3
- "version": "0.2.4",
3
+ "version": "0.3.1",
4
4
  "type": "module",
5
5
  "description": "Pillar-3 chokepoint — classify content crossing every trust boundary (MCP / sub-agent / channel / federation / skill / compaction / tool) with origin metadata and a content-hash LRU cache",
6
6
  "main": "dist/index.js",
@@ -15,8 +15,8 @@
15
15
  "test": "bun test src"
16
16
  },
17
17
  "dependencies": {
18
- "@crewhaus/errors": "0.2.4",
19
- "@crewhaus/prompt-injection-detector": "0.2.4"
18
+ "@crewhaus/errors": "0.3.1",
19
+ "@crewhaus/prompt-injection-detector": "0.3.1"
20
20
  },
21
21
  "license": "Apache-2.0",
22
22
  "author": {
@@ -36,5 +36,5 @@
36
36
  "publishConfig": {
37
37
  "access": "public"
38
38
  },
39
- "files": ["dist", "README.md", "LICENSE", "NOTICE"]
39
+ "files": ["dist", "templates", "README.md", "LICENSE", "NOTICE"]
40
40
  }
@@ -0,0 +1,53 @@
1
+ # boundary-classifier templates
2
+
3
+ Copy-in starting points for operating the item 49 scope-audit drift watch in
4
+ CI. These are **templates, not active workflows** — nothing in this directory
5
+ runs from inside the factory repo.
6
+
7
+ Why this package hosts the template: the drift watch exists to enforce THIS
8
+ package's single-chokepoint invariant. The `boundary-classifier` header
9
+ declares that every cross-trust-domain transition must route through
10
+ `classifyBoundary`, and that "a new boundary that re-implements
11
+ classification inline (or skips it) is a security regression, not a perf
12
+ optimisation" — but until item 49, only the six canonical boundary sites
13
+ were checked, print-only, run-and-forget. The drift watch turns that
14
+ invariant into a baselined CI gate, so the workflow that wires it up lives
15
+ next to the invariant it protects (following the `templates/` convention
16
+ established by `compliance-controls` and `data-retention-engine`).
17
+
18
+ - [`scope-audit-drift.yml`](scope-audit-drift.yml) — GitHub Actions
19
+ PR-trigger template. Copy it into the factory-shaped repository's
20
+ `.github/workflows/` (the audit reads `packages/*/src`, so it applies to
21
+ the factory repo, forks, and vendored monorepos with the same layout) and
22
+ edit the `<PLACEHOLDER>` comments. It runs:
23
+
24
+ ```
25
+ crewhaus doctor --philosophy-alignment --baseline
26
+ ```
27
+
28
+ on every PR that touches `packages/**` or a spec, which:
29
+
30
+ 1. Re-audits the three pillars (boundary sites, tool scopes, package
31
+ presence) **plus** the boundary-drift detector — a conservative scan
32
+ for cross-trust ingress signals (raw MCP SDK imports, inbound channel
33
+ transports, federation peer payloads, chain content decoders) in
34
+ packages that never reference the classification fabric.
35
+ 2. Diffs the findings (by stable id: hash of class + file + symbol)
36
+ against the last accepted baseline at
37
+ `.crewhaus/scope-audit/baseline.json`, and exits non-zero **only on
38
+ NEW findings** — legacy accepted findings never block, so the gate can
39
+ be adopted on a repo with known, deliberate downstream-classification
40
+ transports.
41
+
42
+ To (re)accept the baseline after reviewing findings:
43
+
44
+ ```
45
+ crewhaus doctor --philosophy-alignment --accept-baseline
46
+ git add -f .crewhaus/scope-audit/baseline.json # -f: .crewhaus/ is gitignored
47
+ ```
48
+
49
+ **The baseline must be committed.** The factory `.gitignore` excludes
50
+ `.crewhaus/` (runtime artifacts), so the accepted baseline needs a
51
+ force-add — that is deliberate: accepting findings is a reviewed,
52
+ history-tracked act, not a runtime side effect. A PR whose only change is
53
+ the baseline file IS the review surface for newly accepted findings.
@@ -0,0 +1,67 @@
1
+ # scope-audit-drift.yml — PR-gated scope-audit drift watch TEMPLATE (item 49).
2
+ #
3
+ # This is a TEMPLATE, not an active workflow: copy it into your
4
+ # factory-shaped repository's `.github/workflows/` and edit the
5
+ # <PLACEHOLDER> comments. On every PR that touches package sources or a
6
+ # spec, it re-runs `crewhaus doctor --philosophy-alignment --baseline`:
7
+ # the three-pillar audit (boundary sites, tool scopes) PLUS the
8
+ # boundary-drift detector, diffed against the committed baseline at
9
+ # `.crewhaus/scope-audit/baseline.json`. The job fails ONLY on findings
10
+ # that are NEW relative to the accepted baseline — a fresh cross-trust
11
+ # ingress that skips classifyBoundary trips the PR; the known, deliberate
12
+ # downstream-classified transports you already accepted do not.
13
+ #
14
+ # Prerequisites:
15
+ # - A committed baseline. `.crewhaus/` is gitignored in the factory repo,
16
+ # so accepting is an explicit, reviewed act:
17
+ # crewhaus doctor --philosophy-alignment --accept-baseline
18
+ # git add -f .crewhaus/scope-audit/baseline.json
19
+ # Without one, the gate fails whenever any finding exists (a gate nobody
20
+ # armed must not silently pass).
21
+ # - The audit is repo-shaped: it reads `packages/*/src`, so run it from
22
+ # the repository root of a factory-layout checkout.
23
+
24
+ name: scope-audit-drift
25
+
26
+ on:
27
+ pull_request:
28
+ paths:
29
+ # Package sources — where a new un-classified ingress would land.
30
+ - "packages/**"
31
+ # The CLI that hosts the audit itself.
32
+ - "apps/**"
33
+ # Specs: tool lists / scopes referenced by the pillar audit.
34
+ - "**/crewhaus.yaml"
35
+ # Baseline changes are exactly the review surface for accepted findings.
36
+ - ".crewhaus/scope-audit/baseline.json"
37
+ # Manual runs for baseline reviews outside a PR.
38
+ workflow_dispatch: {}
39
+
40
+ jobs:
41
+ drift-watch:
42
+ runs-on: ubuntu-latest
43
+ steps:
44
+ - uses: actions/checkout@v4
45
+
46
+ - uses: oven-sh/setup-bun@v2
47
+ with:
48
+ # <BUN-VERSION> Pin to the repo's toolchain if you pin elsewhere.
49
+ bun-version: latest
50
+
51
+ - name: Install workspace dependencies
52
+ run: bun install --frozen-lockfile
53
+
54
+ - name: Scope-audit drift gate
55
+ # Exit non-zero ONLY on NEW findings vs .crewhaus/scope-audit/
56
+ # baseline.json (legacy accepted findings never block). Add --json
57
+ # to also persist/emit the machine-readable snapshot + gate verdict,
58
+ # e.g. for uploading as a build artifact:
59
+ # bun apps/cli/src/index.ts doctor --philosophy-alignment --baseline --json > scope-audit.json
60
+ run: bun apps/cli/src/index.ts doctor --philosophy-alignment --baseline
61
+
62
+ # <ON-FAILURE> A red run means a NEW finding. Either fix the ingress
63
+ # (route it through classifyBoundary — see packages/boundary-classifier)
64
+ # or, if it is classified downstream by design, accept it in a
65
+ # reviewed commit:
66
+ # crewhaus doctor --philosophy-alignment --accept-baseline
67
+ # git add -f .crewhaus/scope-audit/baseline.json