nawabari 0.2.0 → 0.4.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/README.md +230 -15
- package/dist/cli.d.ts +5 -0
- package/dist/cli.js +704 -115
- package/dist/cli.js.map +1 -1
- package/dist/contract.js +135 -2
- package/dist/contract.js.map +1 -1
- package/dist/domain/errors.d.ts +1 -1
- package/dist/domain/errors.js +4 -1
- package/dist/domain/errors.js.map +1 -1
- package/dist/domain/sandbox-launcher.d.ts +35 -0
- package/dist/domain/sandbox-launcher.js +679 -0
- package/dist/domain/sandbox-launcher.js.map +1 -0
- package/dist/domain/sandbox.d.ts +190 -0
- package/dist/domain/sandbox.js +363 -0
- package/dist/domain/sandbox.js.map +1 -0
- package/dist/domain/session-backend.d.ts +5 -3
- package/dist/domain/session-backend.js +102 -4
- package/dist/domain/session-backend.js.map +1 -1
- package/dist/domain/session.d.ts +116 -2
- package/dist/domain/session.js +36 -0
- package/dist/domain/session.js.map +1 -1
- package/dist/errors.d.ts +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/git.d.ts +62 -0
- package/dist/git.js +299 -0
- package/dist/git.js.map +1 -1
- package/dist/operation-authorization.d.ts +5 -2
- package/dist/operation-authorization.js +6 -7
- package/dist/operation-authorization.js.map +1 -1
- package/dist/output-budget.d.ts +16 -0
- package/dist/output-budget.js +58 -0
- package/dist/output-budget.js.map +1 -0
- package/dist/presentation.js +28 -4
- package/dist/presentation.js.map +1 -1
- package/dist/registry/atomic.d.ts +24 -0
- package/dist/registry/atomic.js +35 -2
- package/dist/registry/atomic.js.map +1 -1
- package/dist/registry/errors.d.ts +1 -1
- package/dist/registry/errors.js +1 -0
- package/dist/registry/errors.js.map +1 -1
- package/dist/repository-evidence.d.ts +74 -0
- package/dist/repository-evidence.js +7 -0
- package/dist/repository-evidence.js.map +1 -0
- package/dist/resource-claims.d.ts +25 -3
- package/dist/resource-claims.js +57 -5
- package/dist/resource-claims.js.map +1 -1
- package/dist/session-registry.d.ts +68 -7
- package/dist/session-registry.js +422 -149
- package/dist/session-registry.js.map +1 -1
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -5,10 +5,51 @@ agents. It gives each active session one exclusively owned worktree and one
|
|
|
5
5
|
mutable branch. It works without GitHub, `gh`, a network connection, Mottainai,
|
|
6
6
|
or a particular agent runtime.
|
|
7
7
|
|
|
8
|
-
Nawabari governs operations routed through Nawabari.
|
|
9
|
-
ownership boundary, not an operating-system or filesystem
|
|
10
|
-
that already has filesystem permissions can still edit
|
|
11
|
-
directly.
|
|
8
|
+
Nawabari governs operations routed through Nawabari. By default it is an
|
|
9
|
+
authorization and ownership boundary, not an operating-system or filesystem
|
|
10
|
+
sandbox: a process that already has filesystem permissions can still edit
|
|
11
|
+
another worktree directly. This default (legacy) mode is unchanged.
|
|
12
|
+
|
|
13
|
+
The opt-in protected session mode defines a Linux-only OS/filesystem/process
|
|
14
|
+
enforcement boundary underneath the existing session/worktree/resource
|
|
15
|
+
authority (`src/domain/sandbox.ts`, contract
|
|
16
|
+
`nawabari.sandbox-execution.v1`). It binds one existing Nawabari session
|
|
17
|
+
resolved through the authoritative registry/guard path to a typed sandbox
|
|
18
|
+
execution request; it does not create a second session identity. A
|
|
19
|
+
machine-readable capability/doctor report distinguishes required Linux
|
|
20
|
+
primitives (bubblewrap, user/mount/PID/IPC/UTS namespaces) from optional
|
|
21
|
+
defense-in-depth primitives (cgroups v2, Landlock, seccomp, capability
|
|
22
|
+
inspection). When protected execution is requested and a required capability
|
|
23
|
+
is unavailable or the platform is unsupported, resolution fails closed and
|
|
24
|
+
never returns a request that claims the legacy unsandboxed path is
|
|
25
|
+
protected. The lower-level contract remains responsible only for capability
|
|
26
|
+
detection and the typed request/result shape; `resolveSandboxExecutionRequest()`
|
|
27
|
+
returns a request without invoking bubblewrap. The managed `session run`
|
|
28
|
+
launcher consumes that request and establishes the protected boundary. Network
|
|
29
|
+
mode is honestly reported as `inherited` (shared with the host), not isolated.
|
|
30
|
+
|
|
31
|
+
`git nawabari session run --session <id> -- <command> [args...]` is the
|
|
32
|
+
managed protected execution entry point. It resolves the existing session
|
|
33
|
+
through the normal guard authority and compiles a fixed bubblewrap argv; the
|
|
34
|
+
command is passed after an argv terminator and is never interpreted by a
|
|
35
|
+
shell. Resolution or launch failure never falls back to the legacy ambient
|
|
36
|
+
filesystem view.
|
|
37
|
+
|
|
38
|
+
The canonical profile starts from a private root, mounts only the owned
|
|
39
|
+
worktree read-write, gives each session private `/tmp`, `/proc`, HOME and
|
|
40
|
+
cache state, and exposes no sibling worktree or control-plane path. A small
|
|
41
|
+
repository-owned `nawabari/sandbox/shared-home` subtree is the only HOME state
|
|
42
|
+
shared between sessions. Selected host user-tool directories (`~/.local/bin`
|
|
43
|
+
and pnpm's user bin when present) are read-only; credentials and the rest of
|
|
44
|
+
the host HOME are not mounted. `/dev`, system certificates/configuration, and
|
|
45
|
+
the detected runtime are explicit read-only/runtime inputs.
|
|
46
|
+
|
|
47
|
+
On standalone Linux the profile uses existing `/usr`, `/bin`, `/lib*` and
|
|
48
|
+
selected `/etc` paths only when present. On NixOS it additionally selects
|
|
49
|
+
`/nix/store`, `/run/current-system`, `/run/wrappers`, and the per-user profile
|
|
50
|
+
when present; no `/usr` layout is assumed. Missing required paths or namespace
|
|
51
|
+
support produces a stable capability/topology error. Network remains
|
|
52
|
+
inherited by design.
|
|
12
53
|
|
|
13
54
|
## Install
|
|
14
55
|
|
|
@@ -41,6 +82,13 @@ result-schema versions, identity fields, and stable `failure_codes`. The
|
|
|
41
82
|
package version is release metadata; it is not a substitute for the
|
|
42
83
|
machine-contract identifier.
|
|
43
84
|
|
|
85
|
+
The `resource-claims` capability additionally exposes a machine-readable
|
|
86
|
+
`claim_set_replacement` object (`commands`, `atomic: true`,
|
|
87
|
+
`pairing: "adjacent-resource-mode"`, `idempotent_retry: true`,
|
|
88
|
+
`unchanged_on_rejection: true`) describing the atomic multi-claim replacement
|
|
89
|
+
surface documented above, so a caller can discover this contract instead of
|
|
90
|
+
assuming it from the CLI help text.
|
|
91
|
+
|
|
44
92
|
The supported standalone sequence is:
|
|
45
93
|
|
|
46
94
|
```text
|
|
@@ -64,6 +112,8 @@ The result schemas expose the following identities:
|
|
|
64
112
|
| claims | `claim_id`, `session_id`, `resource`, `mode` |
|
|
65
113
|
| authorization | `operation`, `allowed`, `code`, `claim_ids` |
|
|
66
114
|
| checkpoint evidence | `head`, `changed`, `staged`, `unstaged`, `untracked`, `in_claim`, `out_of_claim` |
|
|
115
|
+
| repository evidence | `session_id`, `base_revision`, `head`, `clean`, `paths.stats`, `evidence_hash` |
|
|
116
|
+
| bounded diff | `from_revision`, `to_revision`, `paths`, `stats`, `patch`, `evidence_hash` |
|
|
67
117
|
| commit/push | `commit_sha`, `remote`, `branch`, `target`, `relation` |
|
|
68
118
|
| reconciliation/cleanup | `clean`, `issues`, `candidates`, `cleaned`, `blocked`, `recovery_hints` |
|
|
69
119
|
|
|
@@ -74,6 +124,35 @@ The local lifecycle requires Git and the repository-local registry/lock only;
|
|
|
74
124
|
it does not require Mottainai, GitHub, `gh`, network access, an LLM, or a
|
|
75
125
|
coding-agent runtime.
|
|
76
126
|
|
|
127
|
+
## Read-only repository evidence
|
|
128
|
+
|
|
129
|
+
The evidence family is session-addressed and has no task, Issue, semantic, or
|
|
130
|
+
GitHub interpretation. It is the physical repository authority for one owned
|
|
131
|
+
session:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
git nawabari evidence snapshot --session "$NAWABARI_SESSION_ID" --json
|
|
135
|
+
git nawabari diff --session "$NAWABARI_SESSION_ID" --path src/example.ts --json
|
|
136
|
+
git nawabari diff --session "$NAWABARI_SESSION_ID" --path src/example.ts \
|
|
137
|
+
--patch --max-bytes 32768 --max-hunks 32 --json
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
`evidence snapshot` verifies the registry's repository/worktree/branch owner,
|
|
141
|
+
then reuses checkpoint's exact NUL-safe Git observation for `changed`,
|
|
142
|
+
`staged`, `unstaged`, and `untracked` paths. It also reports canonical per-path
|
|
143
|
+
stats, `clean`, the current `head`, session state, and an `evidence_hash`.
|
|
144
|
+
New sessions persist the exact creation/base revision as `base_revision`;
|
|
145
|
+
legacy records that lack this field report `base_revision: null` and
|
|
146
|
+
`base_revision_proven: false` rather than inferring it from a mutable ref.
|
|
147
|
+
|
|
148
|
+
`diff` requires at least one explicit concrete path and never accepts a glob or
|
|
149
|
+
an empty repository-wide selection. Stats are returned by default. Patch text
|
|
150
|
+
requires `--patch` and is bounded to at most 64 paths, 64 KiB, and 128 hunks;
|
|
151
|
+
the caller may request smaller limits. Unrepresentable Git observations fail
|
|
152
|
+
with `GIT_STATE_AMBIGUOUS`; a requested path whose stat is not exposed by Git
|
|
153
|
+
remains in the result with `available: false` and makes snapshot evidence
|
|
154
|
+
`complete: false`, so no path silently disappears.
|
|
155
|
+
|
|
77
156
|
## Session lifecycle
|
|
78
157
|
|
|
79
158
|
Session IDs are generated automatically as UUIDv7 values. They are immutable
|
|
@@ -91,6 +170,11 @@ git nawabari gc --dry-run --json
|
|
|
91
170
|
git nawabari doctor --json
|
|
92
171
|
```
|
|
93
172
|
|
|
173
|
+
`status --json` reports the resolved `managed_worktree_root` used when
|
|
174
|
+
`session create` omits `--worktree`. `session create --help --json` describes
|
|
175
|
+
all four create options as optional and reports defaults for branch, worktree,
|
|
176
|
+
base (`HEAD`), and label.
|
|
177
|
+
|
|
94
178
|
`session create` provisions a dedicated worktree and mutable branch atomically
|
|
95
179
|
under the repository-scoped mutation lock. The default/integration worktree
|
|
96
180
|
and its protected branch cannot be session resources. `session id` and the
|
|
@@ -108,6 +192,19 @@ every candidate that is not safe. Cleanup revalidates the physical worktree,
|
|
|
108
192
|
branch, and `HEAD` observations immediately before each destructive Git
|
|
109
193
|
operation.
|
|
110
194
|
|
|
195
|
+
Routine `session list` and `status` output excludes `closed` history and is
|
|
196
|
+
limited to 64 records. Use `--all` (or `--history`) for an explicit complete
|
|
197
|
+
history view; closed records remain persisted and are never silently deleted
|
|
198
|
+
by listing or cleanup.
|
|
199
|
+
|
|
200
|
+
`gc` stale eligibility is separate from closed-history retention. Its default
|
|
201
|
+
threshold is 24 hours (`86,400,000` ms), measured from persisted `updated_at`;
|
|
202
|
+
records already in `stale` or `closing` state are eligible, and an otherwise
|
|
203
|
+
live record is also eligible when Git reports its registered worktree as
|
|
204
|
+
missing or prunable. Physical Git/worktree state is authoritative for that
|
|
205
|
+
check. `gc --dry-run` and `gc --apply` do not treat a closed record as a stale
|
|
206
|
+
cleanup candidate.
|
|
207
|
+
|
|
111
208
|
`doctor` includes a non-destructive `reconciliation` check. It reports
|
|
112
209
|
registry/Git ownership drift, including missing or prunable worktrees and
|
|
113
210
|
unregistered physical worktrees, without repairing or deleting anything.
|
|
@@ -119,8 +216,10 @@ same repository registry and protected by the same mutation lock. They are
|
|
|
119
216
|
caller declarations; Nawabari does not infer them from task text or source
|
|
120
217
|
code. Claim JSON exposes `schema_version`, `claim_id`, `session_id`, the
|
|
121
218
|
repository/worktree identities, canonical `resource`, `mode`, and timestamps.
|
|
122
|
-
The
|
|
123
|
-
`exclusive-write`.
|
|
219
|
+
The claim schema version is `2` and supports `read`, `write`, and
|
|
220
|
+
`exclusive-write`. Schema v1 records use different overlap semantics and are
|
|
221
|
+
not interpreted implicitly: an embedding caller must explicitly run
|
|
222
|
+
`SessionRegistry.migrate()` before using them.
|
|
124
223
|
|
|
125
224
|
```bash
|
|
126
225
|
git nawabari session claim --session "$NAWABARI_SESSION_ID" \
|
|
@@ -131,14 +230,45 @@ git nawabari session update --session "$NAWABARI_SESSION_ID" \
|
|
|
131
230
|
git nawabari session release --session "$NAWABARI_SESSION_ID" --json
|
|
132
231
|
```
|
|
133
232
|
|
|
233
|
+
`session update` (and its `resource update` alias) atomically replaces a
|
|
234
|
+
session's _complete_ claim set in one `updateClaims()` transaction, backed by
|
|
235
|
+
the same repository lock as every other mutation. `--resource`/`--mode` are
|
|
236
|
+
repeatable to submit a multi-resource desired set in a single call; each
|
|
237
|
+
`--resource` must be immediately followed by its own `--mode`, so pairing is
|
|
238
|
+
positional adjacency rather than flag order and repeated resources can never
|
|
239
|
+
be associated with the wrong mode:
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
git nawabari session update --session "$NAWABARI_SESSION_ID" \
|
|
243
|
+
--resource src/a.ts --mode exclusive-write \
|
|
244
|
+
--resource src/b.ts --mode exclusive-write \
|
|
245
|
+
--json
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
If any requested claim in the set is invalid or conflicts, the whole update
|
|
249
|
+
is rejected and the session's prior claim set is left unchanged; no partial
|
|
250
|
+
or empty intermediate claim state is ever observable. Submitting the same
|
|
251
|
+
complete desired set again is idempotent. A successful replacement's JSON
|
|
252
|
+
exposes the resulting `claims` together with machine-readable `added` and
|
|
253
|
+
`released` claims.
|
|
254
|
+
|
|
255
|
+
The modes have these normative meanings:
|
|
256
|
+
|
|
257
|
+
- `read`: a non-mutating access declaration. It is not a consistency lease,
|
|
258
|
+
so it may overlap an ordinary `write` claim.
|
|
259
|
+
- `write`: ordinary source-modification authority. It may overlap `read`, but
|
|
260
|
+
not another writer or any `exclusive-write` claim.
|
|
261
|
+
- `exclusive-write`: stronger ownership-sensitive mutation authority. It
|
|
262
|
+
excludes every overlapping claim, including `read`.
|
|
263
|
+
|
|
134
264
|
Overlapping claims use this complete compatibility matrix; non-overlapping
|
|
135
265
|
claims are compatible for every mode:
|
|
136
266
|
|
|
137
|
-
| existing \/ requested | read | write
|
|
138
|
-
| --------------------- | ---------- |
|
|
139
|
-
| read | compatible |
|
|
140
|
-
| write |
|
|
141
|
-
| exclusive-write | conflict | conflict
|
|
267
|
+
| existing \/ requested | read | write | exclusive-write |
|
|
268
|
+
| --------------------- | ---------- | ---------- | --------------- |
|
|
269
|
+
| read | compatible | compatible | conflict |
|
|
270
|
+
| write | compatible | conflict | conflict |
|
|
271
|
+
| exclusive-write | conflict | conflict | conflict |
|
|
142
272
|
|
|
143
273
|
Claims use canonical repository-relative POSIX paths. Literal path segments,
|
|
144
274
|
`*`/`?` segment wildcards, and a complete `**` segment are supported. Empty,
|
|
@@ -149,6 +279,26 @@ garbage-collecting a session releases its claims; no separate claim registry
|
|
|
149
279
|
or claim lock exists. Claims describe ownership state only and do not provide
|
|
150
280
|
OS-level filesystem observation or a filesystem sandbox.
|
|
151
281
|
|
|
282
|
+
An ordinary source change uses `write` and can proceed while another session
|
|
283
|
+
holds a `read` declaration:
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
git nawabari session claim --session "$NAWABARI_SESSION_ID" \
|
|
287
|
+
--resource src/example.ts --mode write --json
|
|
288
|
+
git nawabari authorize --session "$NAWABARI_SESSION_ID" \
|
|
289
|
+
--operation source-write --resource src/example.ts --json
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
A stronger ownership-sensitive operation uses `exclusive-write` and therefore
|
|
293
|
+
requires no overlapping claim:
|
|
294
|
+
|
|
295
|
+
```bash
|
|
296
|
+
git nawabari session claim --session "$NAWABARI_SESSION_ID" \
|
|
297
|
+
--resource src/example.ts --mode exclusive-write --json
|
|
298
|
+
git nawabari authorize --session "$NAWABARI_SESSION_ID" \
|
|
299
|
+
--operation commit --resource src/example.ts --json
|
|
300
|
+
```
|
|
301
|
+
|
|
152
302
|
## Ownership guard
|
|
153
303
|
|
|
154
304
|
`git nawabari guard` is a cheap, side-effect-free authorization decision for a
|
|
@@ -187,6 +337,17 @@ worktree=$(printf '%s' "$created" | jq -r .worktree)
|
|
|
187
337
|
git nawabari session close --session "$session_id" --json
|
|
188
338
|
```
|
|
189
339
|
|
|
340
|
+
For a worker that must receive the protected filesystem/process boundary, use
|
|
341
|
+
the managed launcher instead of starting the worker directly:
|
|
342
|
+
|
|
343
|
+
```bash
|
|
344
|
+
git nawabari session run --session "$session_id" -- node worker.js
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
The launcher owns only the child sandbox topology and process attachment. The
|
|
348
|
+
session registry, worktree/branch ownership, resource claims and lifecycle
|
|
349
|
+
remain the authoritative Nawabari domain state.
|
|
350
|
+
|
|
190
351
|
The orchestrator owns scheduling, prompts, and worker lifetime; Nawabari owns
|
|
191
352
|
only local session identity, worktree/branch ownership, and safe cleanup. No
|
|
192
353
|
Mottainai, GitHub, `gh`, network, or agent-runtime dependency is required.
|
|
@@ -217,9 +378,15 @@ repository-relative resources. Nawabari independently verifies the current
|
|
|
217
378
|
repository, owned worktree, branch, active session, and persisted claims;
|
|
218
379
|
caller-supplied labels do not weaken that decision. The JSON result is the
|
|
219
380
|
automation contract and reports stable allow/deny codes such as
|
|
220
|
-
`MISSING_RESOURCE_CLAIM`, `
|
|
381
|
+
`MISSING_RESOURCE_CLAIM`, `INSUFFICIENT_CLAIM_MODE`, `RESOURCE_CLAIM_CONFLICT`,
|
|
382
|
+
`INVALID_RESOURCE`, and
|
|
221
383
|
the existing ownership/physical-observation codes.
|
|
222
384
|
|
|
385
|
+
`INSUFFICIENT_CLAIM_MODE` means a matching claim exists but its granted mode
|
|
386
|
+
is weaker than the operation requires. Its bounded details identify the
|
|
387
|
+
resource, required access, and matching granted mode names;
|
|
388
|
+
`MISSING_RESOURCE_CLAIM` remains reserved for an absent matching claim.
|
|
389
|
+
|
|
223
390
|
**`authorize` returns an authorization decision only; it does NOT execute the
|
|
224
391
|
operation itself.** Governed commit and push execution use this same decision
|
|
225
392
|
path before invoking bounded Git subprocesses.
|
|
@@ -234,17 +401,51 @@ repository-relative resources. Every resource must be covered by an active
|
|
|
234
401
|
`exclusive-write` claim; all Git-visible changed/staged paths must be in the
|
|
235
402
|
explicit list. JSON includes the resulting `commit_sha`.
|
|
236
403
|
|
|
404
|
+
Commit evidence distinguishes three sets: the caller's **declared/authorized**
|
|
405
|
+
resources (the explicit, claim-covered list a caller passed in), the
|
|
406
|
+
**staged** set Git reports as staged immediately before the commit runs, and
|
|
407
|
+
the **actual committed** set — read back from the resulting commit itself via
|
|
408
|
+
a bounded, NUL-safe `git diff-tree` observation, not inferred from staging
|
|
409
|
+
intent. The `resources` field in a successful `commit --json` result is
|
|
410
|
+
always the actual committed set, proven equal to or a subset of the
|
|
411
|
+
authorized resources; if Git staging/index drift between staging and the
|
|
412
|
+
commit (a hook, a concurrent process) causes the actual commit to contain a
|
|
413
|
+
path outside the authorized set, the result is not reported as an ordinary
|
|
414
|
+
successful commit — it fails with `COMMIT_RESULT_DIVERGED`, which retains the
|
|
415
|
+
resulting `commitSha` (the Git commit already happened) alongside the
|
|
416
|
+
authorized, actual, and divergent path sets for recovery/reconciliation.
|
|
417
|
+
|
|
237
418
|
```bash
|
|
238
419
|
git nawabari commit --session "$NAWABARI_SESSION_ID" \
|
|
239
420
|
--message 'record the local change' --resource src/example.ts --json
|
|
240
421
|
```
|
|
241
422
|
|
|
423
|
+
An optional `--message-pattern <regex>` validates the final message against a
|
|
424
|
+
caller-declared rule before Git is invoked; Nawabari does not own or infer
|
|
425
|
+
commit-message conventions (such as Conventional Commits) itself, so this
|
|
426
|
+
check runs only when a caller explicitly supplies a pattern, and a mismatch
|
|
427
|
+
fails with `INVALID_COMMIT_MESSAGE` before anything is staged. The pattern is
|
|
428
|
+
bounded to 512 characters and is evaluated before the repository lock is
|
|
429
|
+
acquired, so a pathological caller-supplied pattern cannot stall other
|
|
430
|
+
sessions' governed operations. A repository's own `commit-msg` Git hook (if
|
|
431
|
+
any) still runs normally, since governed commit invokes real `git commit`.
|
|
432
|
+
|
|
433
|
+
```bash
|
|
434
|
+
git nawabari commit --session "$NAWABARI_SESSION_ID" \
|
|
435
|
+
--message 'feat: record the local change' --resource src/example.ts \
|
|
436
|
+
--message-pattern '^(feat|fix|docs|refactor|test|chore): .+$' --json
|
|
437
|
+
```
|
|
438
|
+
|
|
242
439
|
Governed push requires explicit claim-covered resources and an explicit
|
|
243
440
|
`--remote`/`--branch` target. Existing upstream and local/remote relation are
|
|
244
441
|
inspected before mutation. A missing upstream requires `--create-upstream`;
|
|
245
|
-
behind or diverged history requires explicit `--force
|
|
246
|
-
`--force-with-lease
|
|
247
|
-
|
|
442
|
+
behind or diverged history requires explicit `--force`. Force pushes use an
|
|
443
|
+
exact `--force-with-lease` bound to the observed remote branch SHA; non-force
|
|
444
|
+
pushes rely on `--no-force` without any lease option. Nawabari fetches only
|
|
445
|
+
the explicit remote branch into a disposable ref when local ancestry is
|
|
446
|
+
missing; it does not update tracking refs or fetch unrelated branches/tags.
|
|
447
|
+
The JSON result includes the immutable `source_sha`, explicit `target_ref`,
|
|
448
|
+
observed `observed_remote_sha`, and relation.
|
|
248
449
|
|
|
249
450
|
```bash
|
|
250
451
|
git nawabari push --session "$NAWABARI_SESSION_ID" \
|
|
@@ -259,6 +460,15 @@ filesystem activity that is reverted, ignored, or otherwise not observable in
|
|
|
259
460
|
the Git checkpoint is outside Nawabari's guarantee; this feature is not an
|
|
260
461
|
OS-level filesystem monitor.
|
|
261
462
|
|
|
463
|
+
Checkpoint canonicalization fails closed: a Git-reported path that cannot be
|
|
464
|
+
represented as a canonical repository resource (traversal, symlink escape, or
|
|
465
|
+
syntax reserved for the claim/glob model) never disappears from evidence.
|
|
466
|
+
Checkpoint fails the whole observation with `GIT_STATE_AMBIGUOUS` instead of
|
|
467
|
+
silently omitting the path, so a caller can never mistake an unrepresentable
|
|
468
|
+
observation for a clean one. This mirrors the strictness governed mutation
|
|
469
|
+
already applies to the same Git-observed paths, so checkpoint evidence is
|
|
470
|
+
never weaker than mutation authorization.
|
|
471
|
+
|
|
262
472
|
## Physical execution context
|
|
263
473
|
|
|
264
474
|
Nawabari treats Git and the canonical filesystem as the authority for every
|
|
@@ -280,6 +490,11 @@ worktree paths, and existing local branches are rejected deterministically;
|
|
|
280
490
|
the repository lock serializes Nawabari provisioning and Git's own ref checks
|
|
281
491
|
remain the final collision authority.
|
|
282
492
|
|
|
493
|
+
An explicit `--base` ref that is empty, malformed, or does not resolve to a
|
|
494
|
+
commit fails with `INVALID_BASE_REF`. The bounded JSON details retain the
|
|
495
|
+
rejected ref, identify `HEAD` as the default recovery base, and include the
|
|
496
|
+
retry hint to omit `--base`; Nawabari does not enumerate or fuzzy-search refs.
|
|
497
|
+
|
|
283
498
|
## Repository state and concurrency
|
|
284
499
|
|
|
285
500
|
The authoritative registry is stored in the repository-common Git directory at
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
import { type DomainResult } from "./domain/errors.js";
|
|
1
2
|
import { type SessionBackend } from "./domain/session.js";
|
|
2
3
|
import { type CliIO } from "./presentation.js";
|
|
4
|
+
import { type SandboxCommand, type SandboxExecutionResult, type SandboxProbe, type SandboxRuntimeLayout } from "./domain/sandbox.js";
|
|
3
5
|
export type CliDependencies = {
|
|
4
6
|
backend?: SessionBackend;
|
|
5
7
|
cwd?: string;
|
|
6
8
|
io?: CliIO;
|
|
7
9
|
version?: string;
|
|
10
|
+
sandboxRunner?: (request: import("./domain/sandbox.js").SandboxExecutionRequest, command: SandboxCommand) => Promise<DomainResult<SandboxExecutionResult>>;
|
|
11
|
+
sandboxProbe?: SandboxProbe;
|
|
12
|
+
sandboxRuntimeLayout?: SandboxRuntimeLayout;
|
|
8
13
|
};
|
|
9
14
|
export declare function runCli(argv: string[], dependencies?: CliDependencies): Promise<number>;
|