Files
mars-nwe/AI.md
2026-06-19 07:32:57 +02:00

531 lines
31 KiB
Markdown

# AI working notes for mars-nwe
This file is the handoff and assistant-rule document. It should keep the next
chat on the current track without forcing it to reconstruct old patch history.
Keep it short enough to read before touching code.
## Start of a new chat
1. Treat `mars-nwe-master` as the root/superproject. The other `mars-*` bundles
are submodules or sibling component sources needed by the root build.
2. Read the root `*.md` files and `doc/*.md` before changing namespace, salvage,
transport or dependency code. The most important active files are
`TODO.md`, `REDESIGN.md`, `ENDPOINTS.md`, this file, and:
- `doc/NSS_IMPORT_NOTES.md`
- `doc/NWFS_SALVAGE_COMPRESSION_TOOLS.md`
- `doc/HANDOFF_AUDIT.md`
- `doc/TOOLBOX_PLAN.md`
3. Do not assume an older bundle is current. Use the latest applied user state
or the latest bundle/patch explicitly accepted by the user.
4. For a fresh build in a new chat, check whether `prepare-local-deps.sh` is
present in the root and run/use it before trying to build; it stages the
uploaded offline third-party tarballs and local-only headers needed by the
current dependency layout.
5. Default language with the user is German; repository documentation remains
English unless the existing file is German.
## Documentation ownership
- `TODO.md` is the active backlog. The top implementation dashboard is allowed
and should stay. Unfinished long-running tracks stay in `TODO.md` until real
implementation/test work closes them.
- `REDESIGN.md` is the durable architecture/design record. Put stable plans,
rationale and completed design decisions there, not patch chronology.
- `AI.md` is for working rules, current handoff state, rejected patches and next
action guidance. Keep it concise; do not append duplicate historic handoff
dumps forever.
- `ENDPOINTS.md` is the decimal/hex NCP audit table.
- `doc/*.md` files are focused topic audits/roadmaps. Keep namespace, NSS
public-core and salvage/compression/tool details in their matching doc files.
When a TODO is finished, remove it from `TODO.md` in the same patch and record
its stable outcome in `REDESIGN.md` or the focused `doc/*.md` file. Do not move
unfinished work out of `TODO.md` merely because its architecture is documented.
## Current accepted patch line
Latest commit after this handoff refresh in an up-to-date tree:
- `docs: refresh NSS handoff after generic runtime naming`
Compare `git log -1 --format="%s"` with this subject. If the tree is older,
check which documentation/import-boundary commits are missing and replay them
before starting new work.
## Current patch handoff block
Last completed work block: **Generic NSS runtime naming**
The code line through `0783 nwnss: use generic NSS runtime naming` is accepted.
The recent runtime-helper patches added shared NSS page/uaccess helpers and then
removed Mars-specific names from the imported NSS path. Inside NSS source and
private NSS compat code, use generic NSS-facing names such as `NSS_USERSPACE`,
`NSS_VIRTUAL_IO`, `NSS_BLOCK_IO`, `NSS_STORAGE_BACKEND_*`, `NSS_IO_BACKEND`,
`NSS_DEFAULT_CODEPAGE`, `NSS_UNITABLE_DIRS`, `NSS_UNICODE` and `NSS_MPK_*`.
Do not add new `MARS_NWE_NWNSS_*` guards, `nwnss*` helper file names or
`Nwnss*` helper symbols in the NSS import itself.
The build/library container is still named `nwnss`: paths such as `src/nwnss/`
and `include/nwnss/`, the CMake target, the `mars_nwe::nwnss` alias and CTest
names like `nwnss.unicode` may keep that name because this project builds the
official NSS code as a MARS-NWE library. The imported code and helper layers
inside that container should look like NSS, not like Mars-specific forks.
The companion-file rule remains role-based, not a blanket `*Userspace` rule:
keep original NSS source files as original-like as possible, add only small
dispatch points, use `*Userspace.c` / `*Userspace.h` for libnwfs/Mars/OtherFS-
facing adapter boundaries, use `*IoUring.c` / `*IoUring.h` for concrete direct
I/O, use `*Fuse.c` / `*Fuse.h` for FUSE-facing provider callbacks, and use
`*Runtime.c` / `*Runtime.h` for NSS runtime/cache/workqueue semantics that
replace former kernel helpers inside the library. Shared helpers use `Nss*`
file/symbol names, for example `NssPageRuntime` and `NssUaccessRuntime`.
Ownership boundaries are current: `nwserv` is the process governor, `nwconn` is
the NCP server, `libnwfs` is the Mars/NCP file wrapper, `libnwnss` is the NSS
provider and future FUSE/io_uring/HostFS/OtherFS boundary owner, and future
NDS/eDirectory compatibility belongs in `libnwnds` over `libnwdirectory` /
`nwdirectory`.
Build/test expectation: the uploaded `ncpfs-2.2.7.tar.gz` is part of the local
dependency set and can be built when full build targets need `libncp`. Separate
build/link success and offline NSS unit tests from server-dependent integration
CTests; the latter require a running configured Mars server and should not be
reported as ordinary offline unit-test failures.
## Directory/NDS work order
- Do not combine LDAPv2/LDAPv3 compatibility work with the FLAIM storage-engine
swap. Keep TinyLDAP/nwdirectory on its existing flatfile/mmap/journal
backend and add behaviour tests first.
- LDAP CTests should start `nwdirectory` on `127.0.0.1:<free-port>` with a
temporary flatfile workdir and test LDAPv2/LDAPv3 bind/search/unbind.
- Add `libnwnds` and console-only `nwsetup` together after LDAPv2/schema flatfile
behaviour is testable. Do not make the first setup path depend on the TUI.
- Later, add FLAIM storage as CMake-selected parallel backend source files that
export the same function names as the flatfile files. Do not break
upstreamable flatfile TinyLDAP code.
Rejected or superseded patches that must not be reused as-is:
- `0380`
- `0398`
- `0403`
- `0677` (`ncpNdpUserspace.c` collector — rejected; search real NSS sources instead)
- `0671` (superseded by `0673`; `virtualIOUserspace.c` removed, real `sharedsrc/virtualIO.c.h` used)
## Current immediate direction
The COMN import/audit chain is complete and the current design boundary is the
libnwnss userspace backend split. The next concrete step is XAttr/LSA import
inside `libnwnss`, not `nwfs` migration yet:
- `extAttrBeast.h` is already at `include/nwnss/include/extAttrBeast.h` (imported
in the COMN sweep, 0659-v2). `lsa.h` is at `include/nwnss/include/lsa.h` (0606).
The remaining XAttr/LSA block is:
1. Copy `shared/sdk/public/zXattr.h` from `nss-common.tar.bz2` to
`include/nwnss/public/zXattr.h`.
2. Create `src/nwnss/lsa/` and import `lsaXattr.c`, `lsaComn.c`, `lsaPrivate.h`,
`lsaSuper.c` from `nss/public_core/lsa/` in `nss.tar.bz2`.
3. Import `extAttrBeast.c` from `nss/public_core/comn/common/` and
`extAttrNSpace.c` from `nss/public_core/comn/namespace/`.
The `nwnss-audit.md` section "XAttr import provenance" lists the authoritative
import order for this block.
- Import real XAttr/LSA definitions from `nss.tar.bz2` and
`nss-common.tar.bz2`.
- Use Novell/Micro Focus/NDK packages only as documentation/reference, not as
code/header provenance.
- Keep original NSS files original-like. Do not use `*Userspace.c` / `*.h` as
a catch-all companion name. Use role-specific companion files instead:
`*Userspace.c` / `*.h` for libnwfs/Mars/OtherFS/HostFS adapter boundaries,
`*Fuse.c` / `*.h` for FUSE/nwnssmount-facing provider callbacks,
`*IoUring.c` / `*.h` for concrete Linux direct/block/file I/O, and
`*Runtime.c` / `*.h` for NSS runtime semantics such as cache state, dirty
tracking, wait barriers, timers, work queues, HMC/page-cache substitutes and
commit/flush coordination. Keep HostFS, OtherFS, FUSE, io_uring and runtime
policy out of imported original files. Current imported runtime candidates are:
`hmc.c` (page/slab/highmem/inode-pagecache shim), `comnIO.c`
(kmap/copy-from-user helpers), `zAPI.c` (uaccess/address-limit helpers), and
`comnCmdline.c` (kernel-style `si_meminfo`). The current tree routes those
through shared `NssPageRuntime` / `NssUaccessRuntime` helpers. Reuse these
helpers for later imports instead of adding fresh local kernel shims.
- `virtualIO` is `_ADMIN`/management virtual-file and XML datastream I/O, not
a disk/block backend. Do not route future `io_uring` design through
`virtualIO`.
- Do not touch or migrate the existing local `nwfs` XAttr code in this phase;
`nwfs` will consume the libnwnss semantics later after the libnwnss side is
tested.
- Treat the XAttr/LSA import as the metadata storage/lookup foundation for later
quota and salvage userspace boundaries, not as their semantic owner. Quota
and salvage remain separate NSS semantic areas, but their valid OtherFS state
should be found through NSS-shaped xattrs or NSS metadata. `libnwnss` owns
those provider operations; `libnwfs` only translates Mars/NCP requests to
them.
- For namespace, keep `libnwnss` as the NSS provider and put Mars/NWFS
compatibility wrappers in `nwfs` later. Most namespace helpers are pure
string/provider operations; `*_generateUniqueName()` needs the same generic
userspace companion-file pattern because HostFS/OtherFS directory collision
lookup may need NSS-shaped xattrs or NSS metadata and must not be added
directly to the original NSS namespace files.
- Quota, salvage, namespace unique-name handling and future backend-sensitive
NSS functions all follow the same ownership split. `libnwnss` is the NSS
provider for semantics imported from `nss`/`nss-common`; `nwfs` is the later
Mars wrapper/adapter. Existing `nwfs` quota and salvage code is only an
implementation inventory and must not be treated as provenance or moved
wholesale into `libnwnss`.
- OtherFS/HostFS quota policy such as Linux `quotactl()`, project-quota or
metadata-only accounting belongs in parallel userspace boundary files such as
`lsaQuotaUserspace.c` or `dirQuotasUserspace.c`, not inline in original NSS
files.
- Salvage follows the same rule: `.salvage` JSON is legacy migration/debug
state only and should not remain authoritative. `.recycle` remains the
OtherFS payload directory, while valid NetWare salvage metadata should come
from NSS-shaped xattrs or later imported NSS salvage metadata through a
`salvageUserspace.c` style boundary.
Before namespace code changes, keep the legacy logging audit in mind: old MARS
accepts numeric debug thresholds from `0` to `99`, but the actual source mostly
uses `1..5`. The future `nwlog` facade should give those normal levels clear
semantic names instead of preserving the old overloaded buckets: `1=error`,
`2=warn`, `3=info`, `4=debug` and `5=trace`. `debug` is local diagnostic detail; `trace` is packet/message/handoff path following across process or provider boundaries. New config should expose the cumulative numeric masks `0`, `1`, `12`, `123`, `1234` and `12345` as synonyms for `off`, `error`, `warn`, `info`, `debug` and `trace`, and use one global `[logging] level` plus optional `[logging.process.<name>] level` overrides; the old numeric `100..106` process entries stay accepted for compatibility. Useful legacy `6..99` traces should
map to `nwlog_detail()` later. `nwlog_detail()` is not part of the normal
`1..5` threshold ladder: normal builds return `0`, while `MAINTAINER_BUILD`
builds may emit detail whenever such a call site is reached. No INI option may
enable it in a normal build.
`nwlog` is the facade/backend plan. Do not add zlog calls or reintroduce a
zlog build dependency; zlog is Apache-2.0 and is not compatible with the
repository's GPL-2.0-only core policy. See `include/nwlog.h` and
`doc/LOG_LEVEL_AUDIT.md`.
Before namespace code changes, keep the terminal-tooling decision in mind when
touching FLAIM tests or admin tools: do not add new direct `curses.h` users.
Future interactive tools should go through the planned `nwtui`/`nwi18n` stack
and the multi-call `nwtoolbox` applet model documented in
`doc/TOOLBOX_PLAN.md`. Configuration parsing/editing is covered in the same
file: use the planned shared `libnwcore` `nw_ini_*` reader/writer so server
code and tools share one policy. Production daemons must not depend on the TUI
stack.
Before namespace code changes, use the handoff audit rules in `doc/HANDOFF_AUDIT.md`.
New namespace/NWFS work must not add new magic `return(-1)` / `return(-2)` paths.
Use the provider names in `include/ncp_endpoint.h` for audits and future endpoint
tables, but do not wire the enum into runtime dispatch until the current
`nwconn` to `nwbind` handoff sites are annotated.
Then continue the NSS namespace track inside `libnwnss`:
1. `libnwnss` is the single userspace library for imported NSS functions and
semantics. Do not create a separate namespace/AdminVol NSS library. The
library should grow from the existing imported runtime into the real NSS
components needed by Mars NWE: namespace, trustee/effective-rights helpers,
XATTR/EA/metadata helpers and later AdminVol semantics.
2. Work bottom-up from the original NSS Linux sources. Use the files in
`nss.tar.bz2` and `nss-common.tar.bz2`; inspect NSS Makefiles/Kbuild-style
source lists as well as includes. If a compile or link error reports an
unresolved NSS symbol, search for and import the matching real NSS `.c` and
header before considering anything else.
3. Do not write semantic wrappers or local replacement models for NSS namespace,
XATTR, trustee or AdminVol logic. The only acceptable wrappers/adaptations
are narrow userspace ports for kernel/OS boundaries such as spinlocks,
allocation, wait/schedule hooks, WIO/console output and similar platform
plumbing.
4. For namespace, target the real `public_core/comn/namespace` code and its real
dependencies under `public_core/comn/common`, `public_core/nss/lib`,
`shared/sdk/include`, `shared/sdk/internal`, `shared/sdk/public` and
`shared/sdk/comnSA`. Keep the `src/nwnss` layout aligned with the original
`public_core` tree, and keep the `include/nwnss` layout aligned with the
original `shared/sdk` tree.
5. AdminVol is a later target because `nameSpace.c` reaches AdminVol and AdminVol
reaches Beast/common code. Before AdminVol cleanup, import the XATTR/EA/
metadata side into `libnwnss` from the original NSS archives so later `nwfs`
can consume real NSS structures and functions instead of keeping local
semantic copies.
6. `libnwnss` must become a userspace NSS semantics library, not a hidden NSS
disk implementation. Do not import block-device, VFS or NSS-disk-layout I/O
blindly. Preserve original disk/VFS-shaped code where possible, but place
HostFS, OtherFS, sidecar, FUSE and `io_uring` policy in explicit parallel
`*Userspace.c` / `*Userspace.h` boundary files. Public userspace APIs should
use libnwnss handles or backend contexts, not real Linux-kernel `struct
dentry`, `struct inode` or `struct super_block` as ABI.
7. `_ADMIN` is expected to become virtual/in-memory semantics in `libnwnss` and
later a userspace `nwadminvol` process served via IPC from `nwconn`/`nwfs`,
with the volume-numbering rule `SYS = 0`, `_ADMIN = 1`, further volumes from
`2`.
8. Keep `src/namspace.c` as NCP glue over the future namespace engine. Do not
expand old MARS `namedos`/`nameos2` as the long-term solution; they are
replacement targets.
9. Namespace pure helpers can stay provider-shaped in `libnwnss`: compare,
wildcard match/replace, ASCII/Unicode conversion, legal-name checks and
component scan for DOS, LONG/OS2, UNIX/NFS, MAC, DATASTREAM and EA.
`*_generateUniqueName()` is not a pure string helper; it needs directory
uniqueness lookup. Preserve the original NSS namespace files and put HostFS,
OtherFS, sidecar or Mars directory-collision policy in a parallel
`nameSpaceUserspace.c` / `nameSpaceUserspace.h` boundary when that path is
implemented.
## NCP notation rule
Always write NCP groups/selectors with both decimal and wire/code hex when
recording protocol details. Examples:
- decimal 87 == wire/code `0x57`
- decimal 90/12 == wire/code `0x5a/0x0c`
- decimal 123/70 == wire/code `0x7b/0x46`
Use `ENDPOINTS.md`, the NDK Core Protocols PDF, WebSDK docs and SDK includes as
references. NetWare 3.x/default compatibility has priority over broad 4.x/NDS
work.
## Patch workflow
- Make small, reviewable patches with one clear subject.
- Inspect current sources before editing; no speculative patching.
- Run at least `git diff --check` before exporting a patch.
- Also run syntax/build/test checks that match the touched files when feasible.
- Export only the `.patch` file by default when producing repository changes.
Do not create or link a bundle unless the user explicitly asks for one.
- Every repository patch must update this `AI.md` with the new final commit
subject in the current patch marker before exporting the patch. If the user
later uploads a bundle from their repository, the marker makes that bundle
self-identifying even when old chat downloads have expired or are unavailable.
- Every repository patch must also replace the single `Current patch handoff
block` in this file with a short description of what the patch was meant to
do. Replace the old block; do not append a new one for every patch.
- Always include a copy/paste `git am <patch-name>.patch` command in the user
response next to the patch download link. This is part of the handoff
contract, not an optional nicety.
- Generate patch mail headers with `Mario Fetka <mario.fetka@disconnected-by-peer.at>`
as the author identity, not an AI/OpenAI identity.
- Do not claim a build/test passed unless it actually ran in the current work
tree.
## Source/layout rules
- Keep imported NSS sources in `libnwnss`, not `libnwcore`. `libnwcore` is
Mars-core only and must not link against `libnwnss` merely because NSS runtime
code exists. NSS tests should be named `nwnss.*`; core tests should only cover
real Mars core helpers such as INI/logging.
- Preserve original NSS API names and original filenames wherever possible.
Import real NSS files from their provenance paths and keep the new layout
recognizable: `public_core/library/...` -> `src/nwnss/library/...`,
`public_core/nss/...` -> `src/nwnss/nss/...`, `public_core/comn/...` ->
`src/nwnss/comn/...`; `shared/sdk/include/...` ->
`include/nwnss/include/...`, `shared/sdk/internal/...` ->
`include/nwnss/internal/...`, `shared/sdk/public/...` ->
`include/nwnss/public/...`, and `shared/sdk/comnSA/...` ->
`include/nwnss/comnSA/...`.
- GPL-2.0-only source imports are allowed when the imported source permits GPLv2
use and the original provenance/license headers are preserved. For Linux
kernel reference material, record that mars-nwe selects GPL-2.0-only.
- Clean NSS staging incrementally. Staging/reference copies under `nwfs` should
not remain just because they are confusing; keep only active Mars adaptation
code there. When a file is needed, import the real NSS source/header into
`libnwnss` in the provenance-preserving layout.
- Do not import broad NSS/OES subsystems blindly, but also do not replace missing
NSS symbols with local semantic wrappers. Use unresolved symbols and original
Makefile object lists to find the next real bottom-up dependency. Only
kernel, VFS, memory-tracking and platform hooks may get small userspace glue.
- `include/nwnss/library` must not be exported as a PUBLIC CMake include directory.
Doing so shadows host headers such as `<stdlib.h>` and `<ctype.h>`, breaking
tests that depend on `include_next` or libc symbols. NSS sources inside the
build use the private dir; external users reference headers through explicit
sub-paths such as `<library/xString.h>` or `<include/omni.h>`.
- `include/nwnss/internal/` holds Mars-private NSS compat headers that must not
become public API: `spinlock.h`, `nssSourceCompat.h`, `nssZosCompat.h`.
- `src/nwnss/sharedsrc/*.c.h` are NSS shared-source implementation fragments.
They must stay in the source tree; do not move them to `include/`.
- Ports (files not from original NSS archives) must be labeled PORT in
`nwnss-audit.md` with a reason. Known ports: `rbpTree.c`, `rand.c`,
`strtol.c`, `utcUserland.c`, allocator wrappers, `wio.c` userspace boundary,
`nebEventPort.c`, Unicode TAB data (GENERATED PORT DATA from Unicode.org, not
Novell blobs). When a PORT entry is found during audit, search for original
`.c` or `sharedsrc/*.c.h` before accepting the port as final.
- For LSA/XAttr/COMN I/O backend work, and for every future NSS function that
needs a companion layer, keep imported original files focused on original
control flow and small dispatch points. Choose the companion suffix by role:
`*Userspace.c` / `*.h` is only for libnwfs/Mars-NCP/OtherFS/HostFS-facing
adapter boundaries; `*Fuse.c` / `*.h` is for FUSE/nwnssmount-facing callbacks;
`*IoUring.c` / `*.h` is for concrete Linux direct/block/file I/O execution;
`*Runtime.c` / `*.h` is for NSS runtime semantics that replace former kernel
helpers inside the library. If both policy selection and direct I/O are
needed, the Userspace/Fuse boundary chooses the path and the IoUring companion
performs only the io_uring-specific work. Shared helper files should use
`Nss*` names such as `NssIoUring.c`, `NssFuse.c` or `NssRuntime.c`, not
`nwnss*` file names. Preprocessor/CMake switches inside the NSS path must
also use generic `NSS_*` names, not `MARS_NWE_NWNSS_*`. `virtualIO` is already
the NSS `_ADMIN`/management virtual-file layer; do not reuse that name for
future disk/block/io_uring backends.
- `*Userspace.c` / `*Userspace.h` companion files are ALLOWED only when they sit
alongside the matching imported original and carry libnwfs/Mars-NCP/OtherFS/
HostFS adaptation that must not go inline, for example `nameSpaceUserspace.c`,
`lsaXattrUserspace.c`, `dirQuotasUserspace.c` or `salvageUserspace.c`.
Collector/stub-filler files such as the rejected `ncpNdpUserspace.c` or the
superseded `virtualIOUserspace.c` are FORBIDDEN: a `*Userspace.c` that exists
only to provide symbols that should come from a real original `.c` or
`sharedsrc/*.c.h` is a stub depot. Always search the original archives first.
- Default `libnwnss` may use: AdminVol, AdminFS, VirtualIO (management/template/
function data streams), in-memory/callback streams, and pure NSS management
callbacks. Real NSS disk-layout I/O, block-device I/O, Kernel VFS I/O, and
cache/file-handle paths that go directly to disk/block/kernel FS require the
`NSS_BLOCK_IO` guard and a future backend context (io_uring, SPDK).
Do not route backend storage through `virtualIO`; that name is taken. Do not
use `NOT_SUPPORTED` to silence Virtual/AdminVol/Callback-IO paths; guard only
real block/disk paths.
- `libnwfs` is the Mars/NCP file compatibility wrapper, not the NSS provider
and not the owner of future storage backends. It translates Mars/NCP file,
namespace, quota, salvage, stream and XAttr operations into `libnwnss` provider
calls, then adapts the result to Mars wire/reply and host persistence rules.
Existing half-finished `nwfs` staging remains ignored during `libnwnss` import
work and should later be removed, replaced or adapted as wrapper code.
- `libnwnss` owns NSS provider semantics and the future real NSS backend
boundaries. Keep their companion roles distinct: `*Userspace.c` / `*.h` for
libnwfs/Mars/OtherFS/HostFS adaptation, `*Fuse.c` / `*.h` for nwnssmount/FUSE
callbacks, `*IoUring.c` / `*.h` for concrete direct I/O, and `*Runtime.c` /
`*.h` for NSS cache/workqueue/wait/dirty runtime semantics.
`nwnssmount` is the future FUSE mount consumer of `libnwnss`; `nwnssmu` is
the future TUI management utility for admin, inspect, repair, quota, salvage,
namespace and XAttr operations.
- `libnwbind` is for bindery identity/storage. NDS/eDirectory compatibility
belongs in a future `libnwnds`, backed by `libnwdirectory`; `nwdirectory` is
the LDAP/TinyLDAP-based directory server. An `nwnds` process may be added
later only when cross-process NDS state, caching, auth brokering, events or
background jobs need a supervised service.
## Service and provider ownership rules
- `nwserv` is the governor/control-plane supervisor for the Mars process tree.
It starts and monitors processes such as `nwconn`, `nwdirectory` and later
optional provider services. It is not the NCP server and should not become the
normal data-plane router for decoded NCP payloads.
- `nwconn` is the NCP server process. It owns client NCP request parsing and NCP
reply construction. For file/volume operations it should call `libnwfs`; for
future NDS/eDirectory identity, authentication, trustee and security
equivalence work it should call `libnwnds`.
- `libnwfs` is the Mars/NCP file wrapper around `libnwnss`. Keep Mars wire
parsing, NCP reply packing, Mars volume options and HostFS/OtherFS adaptation
there; keep NSS semantics in `libnwnss`.
- `libnwnds` is the planned NDS/eDirectory compatibility library. It translates
NetWare concepts such as DN, GUID, UserID, Security Equivalence Vector, tree
context, object/class/attribute mapping and trustee identity lookup to
`libnwdirectory`. Do not hide LDAP/eDirectory policy in `libnwnss` or
`libnwfs`.
- `libnwdirectory` is the library/client layer for `nwdirectory`; `nwdirectory`
is the LDAP/TinyLDAP-based directory server.
- NSS headers such as `eDir.h`, `ncpIDAPI.h` and `ndp_idbroker.h` are boundary
references for GUID/DN/UserID/SEV mapping. They are not a full eDirectory
backend and should point toward `libnwnds`, not toward new directory policy in
`libnwnss`.
- NSS `encp.h` is useful as an NCP wire/layout reference for Mars header
convergence, especially namespace, quota, trustee and salvage layouts. Do not
cast Mars byte buffers directly to imported NSS structs; use byte-safe
parser/builder wrappers or compatibility aliases.
## Namespace rules
- Do not expand old MARS `namedos`/`nameos2` as the long-term solution. They are
replacement targets.
- Import/adapt the NSS namespace engine directly in `libnwnss`, then retire old
MARS namespace logic after tests cover DOS/LONG behaviour. Missing namespace
dependencies must be resolved from the original NSS sources, not by adding
replacement wrappers.
- Stable namespace state belongs in `netware.metadata`: file ID, parent file ID,
DOS name, LONG/OS2 name, MAC name, UNIX/backend name, casefold/hash fields and
namespace flags. `*_generateUniqueName()` must use the generic userspace
companion-file pattern when it needs HostFS/OtherFS directory collision lookup
or metadata/xattr-backed namespace state; do not put that lookup directly into
the original NSS namespace source files.
- Existing Linux files created by Samba, rsync or local admin tools must be
reconciled by libnwfs watcher/scanner work, not by a private side database.
- MAC namespace is a namespace/stream/metadata problem, not a transport problem.
Resource forks and Finder info belong in streams/metadata later.
## Salvage/recycle rules
- Keep `.recycle` as the Samba-compatible deleted-payload backend.
- Make `netware.metadata` on the recycled payload authoritative for deleted
state.
- Treat `.salvage` JSON as legacy migration/debug data only; do not make it a
second long-term authority.
- Samba `vfs_recycle` normally uses rename, so xattrs remain attached to the
recycled inode. Manually copied files in `.recycle` without
`netware.metadata` are not valid NetWare salvage objects unless an explicit
admin repair tool marks them.
- If a compressed file is recycled, the `.recycle` payload should be a normal
uncompressed Linux file; keep previous compression state in `netware.metadata`.
## Compression and stream rules
- Compression belongs in `libnwfs`, not `libnwcore`.
- Future private stream/compression data belongs under
`.nwfs_streams/<stable-file-id>/...`.
- The stable file ID comes from MARS/NWFS/NSS-shaped metadata, not from Linux
inode numbers and not from visible filenames.
- Do not encode compression state in visible names such as `compressed_*`.
## Transport rules
- TCP/IP is implemented in `libnwtransport`, a library that `nwconn` links against; it is not a new daemon.
- Planned files: `src/nwtransport.c`, `src/nwipx.c`, later `src/nwtcp.c`.
- NCP providers stay transport-neutral:
`IPX/TCP -> nwtransport -> nwconn -> dispatcher -> providers`.
- Use audited libowfat API names from the bundled `mars-libowfat` source:
`socket_tcp4()`, `socket_tcp6()`, `socket_bind4_reuse()`,
`socket_bind6_reuse()`, `socket_listen()`, nonblocking accept helpers and
`io_*` readiness helpers.
- IPX config sections use frame tokens without dots:
`8022`, `8023`, `etherii`, `snap`, `tr8022`, `auto`.
- `[transport.ipx.local]` is the internal network; explicit routes use
`[transport.ipx.route.<target>]`.
- If IPX is requested but `socket(AF_IPX, ...)` fails, report that AF_IPX is
unavailable instead of silently falling back.
- A future L2 IPX backend is allowed, but it is an additional backend below
`nwtransport`, not a replacement for the kernel path. Start with Ethernet_II
IPX, SAP/RIP, and NCP socket `0x0451`.
- Do not vendor a capability library for L2 IPX. Open the packet socket and
report missing `CAP_NET_RAW`/`CAP_NET_ADMIN`; root, setcap, or systemd
capabilities are deployment policy.
- Do not copy GPL-3.0-or-later code from the Rust `nwserver` reference. Use only
the observed architecture: userland Ethernet/IPX packet handling, SAP/RIP, and
NCP socket dispatch.
- SPX, if needed, is a later userland layer above IPX. Do not rely on kernel
SPX and do not make namespace work wait for SPX.
- Linux 2.4.37.9 SPX is imported only as reference material in
`src/kernel/af_spx.c` and `include/kernel/spx.h`; do not build it as-is.
## Dependency/source bundle rules
- `mars-nwe-master` is the root repository.
- Uploaded `mars-*` bundles are submodules/sibling components needed in the
configured locations.
- Offline point-release tarballs are staged by `prepare-local-deps.sh`. In a
new chat or clean checkout, use this script as the first dependency/bootstrap
step before CMake/build attempts:
- `yyjson-0.12.0` into `third_party/yyjson`
- `libsodium-1.0.20` into the nested libsodium snapshot path
- `gdbm-1.26` built locally under `.local-deps/prefix`
- PAM and ncurses headers staged while linking to system libraries
- Do not vendor random system headers directly into endpoint/provider code.
## Reference archives
The following archives were used for the NSS import/audit work and are available
for further namespace implementation and NCP structure verification:
- `nss-common.tar.bz2`
- `nss.tar.bz2`
- `ncp__enu.pdf`
- `websdk.tar.gz`
- `include.tar.gz`
### Networked CTest skip policy
Server-dependent NCPFS/AFP/salvage/quota smokes must be visible in CTest but
must not fail ordinary offline builds. Register them with the
`networked;integration` labels and `SKIP_RETURN_CODE 77`. The test launcher
prints `SKIP/WARN` and exits 77 unless `MARS_NWE_RUN_NETWORKED_TESTS=1` and the
required `MARS_NWE_TEST_*` environment variables are present. Use
`ctest -LE networked` for offline unit coverage and `ctest -L networked` for
server-backed integration runs. When the TCP/IP transport test harness lands,
these CTest entries become the path for real local execution.