instar 1.2.23 → 1.2.25

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.
@@ -0,0 +1,52 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- bump: minor -->
4
+ <!-- minor = new capability (ORG-INTENT tradeoff helper — Phase 3). -->
5
+
6
+ ## What Changed
7
+
8
+ **feat(org-intent-runtime): deterministic tradeoff helper for `ORG-INTENT.md` (Phase 3 of 4).**
9
+
10
+ Phases 1 (v1.2.23) and 2 (v1.2.24) surfaced the tradeoff hierarchy from `ORG-INTENT.md` to the Coherence Gate at message-review time and to the agent's session-start context. Both use LLM-based reasoning to resolve values collisions. Phase 3 adds a deterministic standalone helper so code paths OUTSIDE the reviewer — research agents, planning passes, future jobs, the agent itself when asked a direct "which value wins?" question — can consult the hierarchy without paying for an LLM call.
11
+
12
+ The helper is a pure function in a new module:
13
+
14
+ - `src/core/TradeoffResolver.ts` — exported `resolveTradeoff({ valueA, valueB, hierarchy })` returning `{ winner, basis, explanation, matchedIndexA, matchedIndexB }`. No LLM, no fuzzy matching beyond case-insensitive substring containment. Predictable for any caller.
15
+
16
+ It is also exposed via a single HTTP route:
17
+
18
+ - `POST /intent/tradeoff-resolve` — accepts `{ valueA, valueB }` body, loads `ORG-INTENT.md` via `OrgIntentManager.parse()`, applies the resolver, and returns the resolution plus the org's hierarchy.
19
+
20
+ The resolver applies three strategies in priority order:
21
+
22
+ 1. **Pair-pattern** — entries like "customer trust over speed" honor explicit pairwise statements (also accepts `before`, `above`, `trumps`, `wins over`, `beats`).
23
+ 2. **List-order** — case-insensitive substring matching against hierarchy entries; the earlier-indexed match wins.
24
+ 3. **No match** — returns null winner with `basis: 'no-match'` for callers to handle (typically by escalating to value-alignment review).
25
+
26
+ Per `feedback_signal_vs_authority`: the resolver is SIGNAL — it has no authority over outcomes. The Coherence Gate from Phase 1 remains AUTHORITY for any value-alignment block. The reviewer in the gate continues to use LLM-based resolution from the structured hierarchy; this new helper is for non-reviewer code paths.
27
+
28
+ Phase 4 (drift detection job) remains queued.
29
+
30
+ Spec: `docs/specs/ORG-INTENT-TRADEOFF-HELPER-SPEC.md`. ELI16 companion: `docs/specs/ORG-INTENT-TRADEOFF-HELPER-SPEC.eli16.md`. Side-effects review: `upgrades/side-effects/org-intent-tradeoff-helper.md`.
31
+
32
+ ## What to Tell Your User
33
+
34
+ If you have a tradeoff hierarchy in your organizational intent file, your agent can now resolve tradeoff questions deterministically: given two contending values, it can ask the new endpoint which value wins per the hierarchy, and get back a clear answer with a human-readable explanation. The agent uses this when it needs a fast non-LLM tie-break — for example in research or planning code paths.
35
+
36
+ The new endpoint is purely additive; existing behavior is unchanged. If you don't have a tradeoff hierarchy in your file, the endpoint returns a no-match response and callers fall back to LLM-based reasoning.
37
+
38
+ ## Summary of New Capabilities
39
+
40
+ - **POST /intent/tradeoff-resolve** — new HTTP route returning a deterministic tradeoff resolution per the org's hierarchy.
41
+ - **`resolveTradeoff()` exported function** — pure logic helper usable by any new callsite that wants deterministic hierarchy consultation.
42
+ - **Three resolution strategies** — pair-pattern, list-order ranking, and no-match escalation.
43
+ - **Migration parity** — existing agents' CLAUDE.md ORG-INTENT subsection gains a Phase 3 curl line automatically.
44
+
45
+ ## Evidence
46
+
47
+ - Tier 1 unit tests: `tests/unit/TradeoffResolver.test.ts` (16 new tests, all passing). `tests/unit/PostUpdateMigrator-org-intent-runtime.test.ts` extended with 1 new test for Phase 3 migration (8 total, all passing).
48
+ - Tier 2 integration tests: `tests/integration/org-intent-routes.test.ts` extended with 5 new tests for the tradeoff-resolve route (16 total, all passing).
49
+ - Tier 3 E2E lifecycle tests: `tests/e2e/org-intent-tradeoff-lifecycle.test.ts` (5 tests mirroring production wiring through `AgentServer` and `createRoutes`, all passing — including the "feature is alive" 200-not-503 check).
50
+ - Type-check: `npx tsc --noEmit` clean.
51
+ - Lint: clean.
52
+ - The full test suite must remain green before merge per Zero-Failure Standard.
@@ -0,0 +1,87 @@
1
+ # Side-effects review — org-intent session-start injection (Phase 2)
2
+
3
+ Spec: `docs/specs/ORG-INTENT-SESSION-START-INJECTION-SPEC.md`
4
+ ELI16: `docs/specs/ORG-INTENT-SESSION-START-INJECTION-SPEC.eli16.md`
5
+ Phase: 2 of 4. Phase 1 (gate wiring) shipped as v1.2.23 (PR #315). Phase 3 (tradeoff helper) and Phase 4 (drift detection job) are queued.
6
+
7
+ ## Surface map
8
+
9
+ | Change | File | Type |
10
+ |---|---|---|
11
+ | Exported `formatOrgIntentForSessionStart()` formatter | `src/core/OrgIntentManager.ts` | Additive function export |
12
+ | New `GET /intent/org/session-context` HTTP route | `src/server/routes.ts` | Additive route |
13
+ | Session-start hook fetches + injects parsed ORG-INTENT block | `src/core/PostUpdateMigrator.ts` (`getSessionStartHook`) | Behavior change to agent-installed hook script |
14
+ | CLAUDE.md ORG-INTENT subsection updated (mentions Phase 2) | `src/scaffold/templates.ts` + `PostUpdateMigrator.migrateClaudeMd()` | Doc + migration |
15
+ | Tier 1 unit tests (formatter + migration) | `tests/unit/OrgIntentManager-session-start-format.test.ts`, extended `PostUpdateMigrator-org-intent-runtime.test.ts` | Test addition |
16
+ | Tier 2 integration tests | Extended `tests/integration/org-intent-routes.test.ts` | Test addition |
17
+ | Tier 3 E2E test | `tests/e2e/org-intent-session-context-lifecycle.test.ts` | Test addition |
18
+
19
+ ## Over-block analysis
20
+
21
+ **Could the injection push the agent's context over a token budget?**
22
+
23
+ The block size scales with the `ORG-INTENT.md` file size — the formatter doesn't add content; it just labels and structures what's already there. A typical authored `ORG-INTENT.md` is dozens of bullets across four sections — comfortably under 500 tokens. The cap is the source file itself; an organization with a 10-page ORG-INTENT.md will see 10 pages injected. That's a feature, not a bug — but operators should be aware that very large intent files consume context.
24
+
25
+ **Could the hook fail in a way that disrupts session start?**
26
+
27
+ No. The hook uses `curl -sf --max-time 4` and a wrapping `if [ -n "$ORG_INTENT_RESPONSE" ]; then ... fi`. Any failure path (route unreachable, 503, network timeout, malformed JSON) results in silent skip. The session continues normally. The Coherence Gate from Phase 1 still enforces the contract at outbound message time, so missing the session-start injection never compromises constraint enforcement.
28
+
29
+ **Could the new route be abused / DoS'd?**
30
+
31
+ The route reads `ORG-INTENT.md` from the agent's state dir on every request — bounded local disk read, no LLM call, no DB query. The auth middleware enforces Bearer-token gating. Rate at which an attacker could call it is also bounded by the same auth gate. No new abuse surface beyond `GET /intent/org` (which already existed).
32
+
33
+ ## Under-block analysis
34
+
35
+ **What does the injection NOT catch?**
36
+
37
+ - A subtle constraint violation the agent doesn't recognize when drafting. The injection helps the agent *understand* the constraints; the gate is what actually *enforces* them. If the agent's reasoning misses a constraint applicability, the gate catches it.
38
+ - Constraint applicability scoping. A constraint like "never quote internal pricing externally" depends on knowing if the recipient is external. The injection surfaces the constraint; the agent must reason about applicability. Phase 3+ may add scoping metadata to constraints.
39
+ - Mid-session ORG-INTENT.md changes. The injection happens at session start. Edits during a session do not propagate until next session.
40
+
41
+ ## Level-of-abstraction fit
42
+
43
+ The formatter lives in `src/core/OrgIntentManager.ts` alongside the parser — the right place for a pure rendering function. The HTTP route lives in `src/server/routes.ts` next to `GET /intent/org`. The hook update lives in `PostUpdateMigrator.getSessionStartHook()`, the canonical source for session-start hook content. No new abstractions introduced.
44
+
45
+ ## Signal-vs-authority compliance
46
+
47
+ The session-start injection is **SIGNAL** — it informs the agent's reasoning but has no authority to refuse or modify outbound messages. The Coherence Gate (Phase 1) remains the **AUTHORITY**: constraint violations are blocked at outbound-message review time regardless of whether the agent saw the injection at session start.
48
+
49
+ This separation is intentional. A signal-only injection is robust to malformed `ORG-INTENT.md`, route failures, and hook timeouts — the worst case is "the agent doesn't see the contract this session," not "the agent ignores the contract." The authority layer (the gate) catches what the signal misses.
50
+
51
+ ## Interactions with existing systems
52
+
53
+ | System | Interaction | Risk |
54
+ |---|---|---|
55
+ | Coherence Gate (Phase 1) | None — different layer, different lifecycle | None |
56
+ | `GET /intent/org` | Sibling route — same data, different formatting | None |
57
+ | Session-start hook (existing) | Adds one new fetch + inject block alongside identity, topic, integrated-being, soul, working-memory, etc. | Low — fail-open, bounded by curl --max-time 4 |
58
+ | Working memory injection | Independent — both contribute to session-start context | Token cost is additive but bounded |
59
+ | PostUpdateMigrator other migrations | New migration path operates on an isolated content region | Low — content-sniff guards |
60
+ | Existing `getSessionStartHook()` content | Added inline block; rest unchanged | Low — verified by template parity test pattern |
61
+
62
+ ## Rollback cost
63
+
64
+ Low. Three options:
65
+
66
+ 1. **Code revert**: `git revert <PR-merge-sha>` removes route + hook block + format function. Tests would need removal too.
67
+ 2. **Soft revert via hook bypass**: edit installed `session-start.sh` to remove the curl/python3 block. The route remains but is just an unused HTTP endpoint.
68
+ 3. **Soft revert via empty file**: replace `ORG-INTENT.md` with template-only content; the route returns `{ present: false }` and no injection happens. The Phase 1 gate also gracefully degrades on template-only.
69
+
70
+ No data migration to roll back. No file format changes. The Phase 1 wiring is unaffected by this change.
71
+
72
+ ## Test coverage summary
73
+
74
+ | Tier | File | Tests | Status |
75
+ |---|---|---|---|
76
+ | 1 (unit) | `tests/unit/OrgIntentManager-session-start-format.test.ts` | 6 | ✓ passing |
77
+ | 1 (unit) | `tests/unit/PostUpdateMigrator-org-intent-runtime.test.ts` (extended) | 7 (2 new for Phase 2) | ✓ passing |
78
+ | 2 (integration) | `tests/integration/org-intent-routes.test.ts` (extended) | 11 (4 new for Phase 2) | ✓ passing |
79
+ | 3 (E2E lifecycle) | `tests/e2e/org-intent-session-context-lifecycle.test.ts` | 3 | ✓ passing |
80
+
81
+ ## Open follow-ups (deferred to later phases, NOT this PR)
82
+
83
+ - Phase 3: `POST /intent/tradeoff-resolve` standalone helper.
84
+ - Phase 4: periodic drift detection job sampling recent outbound actions vs intent.
85
+ - Mid-session ORG-INTENT.md change propagation (fs.watch or signal-based reinject).
86
+ - Per-channel constraint scoping (some constraints external-only, others universal).
87
+ - Cache layer in front of the route if call rate becomes notable (currently bounded by session-start frequency, which is ~1 per session).
@@ -0,0 +1,88 @@
1
+ # Side-effects review — org-intent tradeoff helper (Phase 3)
2
+
3
+ Spec: `docs/specs/ORG-INTENT-TRADEOFF-HELPER-SPEC.md`
4
+ ELI16: `docs/specs/ORG-INTENT-TRADEOFF-HELPER-SPEC.eli16.md`
5
+ Phase: 3 of 4. Phase 1 shipped as v1.2.23 (PR #315). Phase 2 shipped in PR #317. Phase 4 (drift detection job) queued.
6
+
7
+ ## Surface map
8
+
9
+ | Change | File | Type |
10
+ |---|---|---|
11
+ | Pure `resolveTradeoff()` function + `TradeoffResolution` type | `src/core/TradeoffResolver.ts` (new file) | Additive module |
12
+ | New `POST /intent/tradeoff-resolve` HTTP route | `src/server/routes.ts` | Additive route |
13
+ | CLAUDE.md ORG-INTENT subsection adds Phase 3 curl line | `src/scaffold/templates.ts` + `src/core/PostUpdateMigrator.ts` | Doc + migration |
14
+ | Tier 1 unit tests (resolver + migration) | `tests/unit/TradeoffResolver.test.ts` (new), `tests/unit/PostUpdateMigrator-org-intent-runtime.test.ts` (extended) | Test addition |
15
+ | Tier 2 integration tests | `tests/integration/org-intent-routes.test.ts` (extended) | Test addition |
16
+ | Tier 3 E2E test | `tests/e2e/org-intent-tradeoff-lifecycle.test.ts` (new) | Test addition |
17
+
18
+ ## Over-block analysis
19
+
20
+ **Could the new helper ever block an outbound message?**
21
+
22
+ No. The resolver is pure deterministic logic with no authority over outcomes. The Coherence Gate from Phase 1 remains the only place where ORG-INTENT can block a message. Per `feedback_signal_vs_authority`, the resolver is SIGNAL — it tells callers what the hierarchy says; it never refuses anything.
23
+
24
+ **Could the route be DoS'd?**
25
+
26
+ The route reads `ORG-INTENT.md` from the agent's state dir on every request — bounded local disk read, no LLM call, no DB query. Auth middleware enforces Bearer-token gating. No new abuse surface beyond what `GET /intent/org` already exposes.
27
+
28
+ **Could the resolver return a wrong winner?**
29
+
30
+ Three risk vectors:
31
+
32
+ 1. **String matching false positives** — value "speed" might substring-match "execution speed of light." The resolver's case-insensitive substring containment is permissive by design. For ambiguous cases the caller should be specific in their value strings. This is documented in the resolver's source comments.
33
+
34
+ 2. **Same-entry tie** — if both values appear in the same hierarchy entry without a "X over Y" pair pattern, the resolver returns `basis: 'tie'` and `winner: null`. Caller decides what to do — typically escalates to the value-alignment reviewer.
35
+
36
+ 3. **Pair-pattern misparsing** — the resolver only recognizes the six listed patterns (`over`, `before`, `above`, `trumps`, `wins over`, `beats`). Other phrasings fall through to list-order matching. This is acceptable; future iterations can extend the pattern list.
37
+
38
+ ## Under-block analysis
39
+
40
+ **What does the resolver NOT catch?**
41
+
42
+ - Multi-value tradeoffs (three or more contending values). The function signature is `(valueA, valueB)`. Callers wanting to resolve a three-way race must call the resolver twice and compose. Future iteration may add `resolveTradeoffN([...])` if demand surfaces.
43
+ - Context-dependent applicability. A constraint like "customer trust over speed" may not apply in some channels (e.g. an internal status update where speed is fine). The resolver doesn't model channels; the caller decides applicability.
44
+ - Stale state. The route reads `ORG-INTENT.md` on every request, so edits propagate immediately — but if the hierarchy is changed mid-session, the agent's session-start injection (Phase 2) still shows the old version until next session.
45
+
46
+ ## Level-of-abstraction fit
47
+
48
+ `TradeoffResolver` is pure logic, single file, no dependencies — the right level for a deterministic helper. The HTTP route lives next to the other `/intent/*` routes. No new abstractions introduced. The helper is intentionally NOT exposed as a class — a free function is the right shape for a stateless pure computation.
49
+
50
+ ## Signal-vs-authority compliance
51
+
52
+ The resolver is **SIGNAL** — pure deterministic computation, no authority over outcomes. The Coherence Gate from Phase 1 remains **AUTHORITY** for any value-alignment block. Callers who consult the resolver are free to override its conclusion. The reviewer in the gate is also free to disagree with the resolver's `basis: 'list-order'` reading if it has better contextual reasoning.
53
+
54
+ This is exactly the signal/authority separation per `feedback_signal_vs_authority`. Future Phase 4 drift detection should follow the same pattern — emit a digest signal, never block.
55
+
56
+ ## Interactions with existing systems
57
+
58
+ | System | Interaction | Risk |
59
+ |---|---|---|
60
+ | Coherence Gate (Phase 1) | None — gate's value-alignment reviewer continues using LLM-based resolution | None |
61
+ | Session-start injection (Phase 2) | None — independent surface | None |
62
+ | `GET /intent/org` | Sibling route — same source data, different output shape | None |
63
+ | `OrgIntentManager.parse()` | Resolver consumes the `tradeoffHierarchy` field | Read-only — no mutation |
64
+ | Existing routes | No conflict — `/intent/tradeoff-resolve` is a new path | None |
65
+
66
+ ## Rollback cost
67
+
68
+ Low. Three options:
69
+
70
+ 1. **Code revert**: `git revert <PR-merge-sha>` removes the new file, the new route, and the new test files. No data migration to roll back.
71
+ 2. **Soft revert via 404**: rename the new route in `routes.ts`. The `TradeoffResolver` module remains as dead code; nothing else consumes it.
72
+ 3. **Just don't call it**: the route is opt-in. No code path that existed before this PR calls the new route, so leaving it un-called is equivalent to it not existing.
73
+
74
+ ## Test coverage summary
75
+
76
+ | Tier | File | Tests | Status |
77
+ |---|---|---|---|
78
+ | 1 (unit) | `tests/unit/TradeoffResolver.test.ts` | 16 | ✓ passing |
79
+ | 1 (unit) | `tests/unit/PostUpdateMigrator-org-intent-runtime.test.ts` (extended) | 8 (1 new for Phase 3) | ✓ passing |
80
+ | 2 (integration) | `tests/integration/org-intent-routes.test.ts` (extended) | 16 (5 new for Phase 3) | ✓ passing |
81
+ | 3 (E2E lifecycle) | `tests/e2e/org-intent-tradeoff-lifecycle.test.ts` | 5 | ✓ passing |
82
+
83
+ ## Open follow-ups (deferred to later phases, NOT this PR)
84
+
85
+ - Phase 4: periodic drift detection job sampling recent outbound actions vs intent.
86
+ - `resolveTradeoffN([...])` for multi-way tradeoff resolution.
87
+ - Channel/recipient scoping on constraints + tradeoffs.
88
+ - Optional LLM fallback when `basis: 'no-match'` — caller-controlled escalation path.